1

I'm having issues understanding some concepts of Object in apex and trying to write a test class for it. Here is my class

global void myLeadsCities(Map<String,Object> inputJsonMap) {
    Set<String> leadCities = new Set<String>();
    List<Object> objs = (List<Object>)inputJsonMap.get('leads');
    for (Object o : objs) {
        Map<String, Object> leadFields = (Map<String, Object>)o;
            String city = (String)leadFields.get('city');
    }
}

Test Class:

@isTest
global class LeadCitiesTest {
    @isTest
    static void testMethod() {
        List<CustomObj> objs = new List<CustomObj>();
        CustomObj o = new CustomObj('New York');
        CustomObj o1 = new CustomObj('Boston');
        objs.add(o);
        objs.add(o1);
        List<Object> anyObj = new List<Object>();
        anyObj = (List<Object>) objs;
        
        Map<String, Object> inputMap = new Map<String, Object>();
        inputMap.put('city', anyObj);
        Test.startTest();
        LeadInfo leadDedup = new LeadInfo();
        leadDedup.myLeadsCities(inputMap);
        Test.stopTest();
    }
    
    public class CustomObj {
        public String city;
        public customObj(String c) {
            city = c;
        }
    }
}

ERROR: Message Invalid conversion from runtime type LeadCitiesTest.CustomObj to Map<String,ANY>

I understand CustomObj is not Object but need help with the test coverage here.

1 Answer 1

5

Your code under test appears to be accepting data that has been deserialized from JSON via deserializeUntyped(). This means that the data will consist only of primitive values, such as strings and integers, and Lists and Maps with string keys.

Your test class is constructing a custom object rather than a primitive data structure that comes out of JSON deserialization, so the input data to your code under test does not match the assumptions that code is making about its types.

When you work with untyped JSON deserialization, you'll often see collections like List<Object> and Map<String, Object>. This means that the type of the contained objects is not known to the compiler at the time of writing the code. It doesn't mean, however, that you can place any type there at any time, because (as here) the code processing this data likely has specific expectations about what type the value will have at runtime.


Since the custom object exists only inside your test class as an inner object (it's not part of your application), I think you need to simply remove it and construct the data more like this:

Map<String, Object> inputMap = new Map<String, Object>{
    'leads' => new List<Object>{
        new Map<String, Object> {
            'city' => 'Boston'
        },
        new Map<String, Object> {
            'city' => 'New York'
        }
    }
};

That matches the expectations of your code under test.

Note, however, that at present the code under test does nothing. You will have an easier time writing tests once you define the outcome of the code so that you can assert against it.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .