[SalesForce] recommended way to unit test JSON Parser based on JSON.deserializeUntyped calls

We are doing a lot of JSON data parsing in our solution by own JSON parser implementation. I wonder how can I write unit tests for JSON parser. Is it good approach to load JSON data from static resources? How can I get JSON as string from static resource? Do I need to use StaticResourceCalloutMock when I only test JSON parser methods that simply get input as string and return SObject?

Best Answer

If the JSON is reasonably small then I would build it in the unit tests. That allows you to generate various permutations and always have the values to hand to assert against.

The best way to do that (when you don't have Apex classes generated by e.g. JSON2Apex) is by creating nested Map<String, Object>s and then applying JSON.serialize. This ensures correct escaping and avoids ugly and error-prone string quoting and concatenation. Here is an example:

List<Map<String, Object>> types = new List<Map<String, Object>>{
    new Map<String, Object>{
        'name' => 'Test Note added to Claim',
        'sobType' => String.valueOf(Note.SObjectType),
        'polymorphicParentSobType' => String.valueOf(Claim__c.SObjectType) 
    },
    new Map<String, Object>{
        'name' => 'Test Note Title changed',
        'sobType' => String.valueOf(Note.SObjectType),
        'sobField' => String.valueOf(Note.Title) 
    }
};
String jsonString = JSON.serilize(types);

At first sight, this looks pretty confusing, but it is just using a List for any JSON array [...] and a Map for any JSON object {...}. And Apex has good data initialization syntax available such as => for setting up map name-value pairs. You don't have to build it all at once either, you can set up pieces and then assemble them.

If the JSON is very large and you have examples that you want to use in tests then static resources are one way to go. You can query static resources (in product code or test code) like this:

Set<String> staticResourceNames = ...;
for (StaticResource sr : [
        select Name, Body
        from StaticResource
        where Name in :staticResourceNames
        ]) {
     String jsonString = sr.Body.toString();
     ...
}
Related Topic