13

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
    Commented 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. Commented Apr 22, 2014 at 14:44
  • Yep would be good to understand the root cause.
    – Keith C
    Commented 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
    Commented Apr 22, 2014 at 16:12
  • 1
    Certainly seems like a bug, I flagged it with the apex team.
    – superfell
    Commented 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? Commented Apr 22, 2014 at 18:40
  • 1
    @JuanAlvarez Open a case with Salesforce Support
    – Alan Morey
    Commented Apr 22, 2014 at 18:42
  • Reported! I will let you know as soon as I have news. Thanks! Commented 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. Commented 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 Commented Apr 23, 2014 at 21:14
1

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.

You must log in to answer this question.

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