12

I am facing an issue when converting an Opportunity to and then from JSON. If I put that in a test, the assertion fails when comparing both Opportunities.

Here is my code:

Test case:

static testMethod void opportunityCanBeConvertedToJSONFormatAndBack () {

    Opportunity opportunity = Build.anOpportunity().build();
    Opportunity jsonOpportunity = Opportunities.opportunityFromJSON( Opportunities.opportunityToJSON(opportunity) );

    // all this assertions pass
    System.assertEquals(opportunity.Name, jsonOpportunity.Name);
    System.assertEquals(opportunity.StageName, jsonOpportunity.StageName);
    System.assertEquals(opportunity.AccountId, jsonOpportunity.AccountId);
    System.assertEquals(opportunity.Amount, jsonOpportunity.Amount);
    System.assertEquals(opportunity.Sale_Steps__c, jsonOpportunity.Sale_Steps__c);
    System.assertEquals(opportunity.CloseDate, jsonOpportunity.CloseDate);

    // this assertion fails... 
    System.assertEquals(opportunity, jsonOpportunity);
}

The Build class creates the opportunity as follows:

public Opportunity build () {
    if (account == null) {
        account = anAccount().build();
        insert account;
    }
    Opportunity opp = new Opportunity(Name = name,
                                      CloseDate = Date.today(),
                                      StageName = 'Opportunity stage name',
                                      AccountId = account.Id,
                                      Amount = this.anAmount,
                                      Sale_Steps__c = saleStep
    );

    return opp;
}

And finally, this is how the Opportunities class makes the JSON convertion:

public static String opportunityToJSON(Opportunity opp) {
    return System.Json.serialize(opp);
}

public static Opportunity opportunityFromJSON(String json) {
    return (Opportunity) System.Json.deserialize(json, Opportunity.class);
}

Finally, the error message shows the same string conversion for the Opportunities,

Assertion Failed: 
Expected: Opportunity:{Name=An opportunity, StageName=Opportunity stage name, Amount=null, AccountId=001i000000oVNChAAO, Sale_Steps__c=Prospecting, CloseDate=2014-04-22 00:00:00}, 
Actual: Opportunity:{Name=An opportunity, StageName=Opportunity stage name, Amount=null, AccountId=001i000000oVNChAAO, Sale_Steps__c=Prospecting, CloseDate=2014-04-22 00:00:00}

so I am guessing that it should be a deeper comparison that is failing (maybe a TZ, or something inside the Account?), but I can't figure it out, so any help will be really appreciated.

Thanks in advance! Juan M.

Update

I forgot to say that using System.assert and comparing with == also fails.

6
  • 3
    You may have already seen this thread, but fyi: developer.salesforce.com/forums?id=906F00000008xsmIAA.
    – Keith C
    Apr 22, 2014 at 14:01
  • Thanks for the suggestion! I have seen that thread and all the proposed solutions involve comparing objects field by field, or using String representations. I am currently using one of this methods, but I see it as a workaround. I am trying to find out why standard comparison does not work, or why it can't be used. Apr 22, 2014 at 14:44
  • Yep would be good to understand the root cause.
    – Keith C
    Apr 22, 2014 at 14:47
  • 1
    I suggest you go through all the fields using describe and assert each one individually. According to documentation, the == is based in comparing each field. This should point to what changes. salesforce.com/us/developer/docs/apexcode/Content/…
    – Acuariano
    Apr 22, 2014 at 16:12
  • 1
    Certainly seems like a bug, I flagged it with the apex team.
    – superfell
    Apr 23, 2014 at 21:28

2 Answers 2

3

I tried comparing each field separately using describe and it works. But the equals for opportunity still fails. I think this is a bug. Here's the code:

@isTest
class OpportunityToJsonBug {
    private static testMethod void testBug() {
        Opportunity opp = new Opportunity(Name = 'Test Opp', StageName = 'Prospecting');
        String json = System.Json.serialize(opp);
        Opportunity jsonOpp = (Opportunity) System.Json.deserialize(json, Opportunity.class);
        Map<String, Schema.SObjectField> M = Schema.SObjectType.Opportunity.fields.getMap();
        for(String fieldName :  M.keySet()) {
             Object oppField  = opp.get(fieldName);
             Object jsonOppField  = jsonOpp.get(fieldName);
             System.assertEquals(oppField, jsonOppField, 'Failed when comparing field ' + fieldName);
        }

        Opportunity controlOpp = new Opportunity(Name = 'Test Opp', StageName = 'Prospecting');
        System.assertEquals(opp, controlOpp);

        // fails here...        
        System.assertEquals(opp, jsonOpp);
    }
}
7
  • Thanks! Where is one supposed to report this? Apr 22, 2014 at 18:40
  • 1
    @JuanAlvarez Open a case with Salesforce Support
    – Alan Morey
    Apr 22, 2014 at 18:42
  • Reported! I will let you know as soon as I have news. Thanks! Apr 22, 2014 at 18:56
  • Not sure if it helps, but I was able to replicated this for all Fields on an Account and got same error. Apr 23, 2014 at 21:13
  • Opportunity a = new Opportunity(name='test1'); Account a1 = new Account(name = 'woop'); Account a2 = new Account(name = 'woop'); Account a3 = (Account)JSON.deserialize('{"name" : "woop"}', Account.class); Account a4 = (Account)JSON.deserialize(JSON.serialize(a1), Account.class); System.debug( a1 == a2 ); // true System.debug( a1 === a2); // false System.debug( a3 == a1 ); // true System.debug( a4 == a1 ); // false but should be true Apr 23, 2014 at 21:14
0

Looks like it has been fixed in Winter 16.

http://releasenotes.docs.salesforce.com/en-us/winter16/release-notes/rn_apex_json_ids.htm

Thanks! Juan M.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.