deserializing JSON to object: different behavior in unit test vs API?

So let’s say I’ve got a class that looks like this:

public class APIParams {
        public String name; 
        public String category; 
        public Boolean taxable = false;
}

Then I have a custom REST webservice (apexrest) that takes JSON and deserializes it to an object of this class, like so:

    String rawParams = RestContext.request.requestBody.toString();
    APIParams p = (APIParams) JSON.deserialize(rawParams, APIParams.class);

The difference in behavior comes in how it handles it if I don’t pass in that “taxable” property. Here’s what I’m seeing:

  • In a unit test, if I pass in JSON that doesn’t include “taxable”, I end up with an object where taxable = false. (i.e. it respects the default value in the class definition)
  • OTOH, if I pass in the same JSON via the API, I end up with an object where taxable = null. No default is applied.

Is there some sort of rhyme & reason to this difference, or is this effectively a bug? As you might imagine, this makes it difficult to write tests that effectively cover the behavior that we will see in production.

Thanks!

Answer

I tried a test as you mentioned but it has the same behavior on Test as well as on real usage.

@IsTest
public class APIParamsTest {
    @isTest static void test() {
        String rawParams = '{"name":"karthik"}';
        APIParams p = (APIParams) JSON.deserialize(rawParams, APIParams.class);
        System.assert(p.name == 'karthik');
        System.assert(p.taxable == false);
    }
}

Even in this test the assert on taxable field fails.

  • I am not sure how its different from the test you wrote, but I find the behavior consistent everywhere.

  • To get consistent behavior I think its better to handle it in getter than through default variables As @crop1645 mentioned.

    return taxable == null ? false : taxable;

Attribution
Source : Link , Question Author : mscholtz , Answer Author : karthikselva

Leave a Comment