0

I am writting a test method, where I have to set closedate of a case record to an old date.

I know, i can make Status to "closed", but it will give you close date as Today.

Is there any other way, where I can set the close date to an old date?

2 Answers 2

1

You should be able to do this, and set other system date fields, using JSON.deserialize(). For example (setting CreatedDate):

@isTest 
private class CaseTest{ 
static testmethod void testLoadData(){ 
String caseJSON = '{"attributes":{"type":"CasSe","url":"/services/data/v25.0/sobjects/Case/500E0000002nH2fIAE"},"Id":"500E0000002nH2fIAE","Status":"Open","CreatedDate":"2012-10-04T17:54:26.000+0000"}'; 
Case c = (Case) JSON.deserialize(caseJSON, Case.class ); 
System.debug('Test case:' + c.createdDate); 
System.debug('Test caseId:' + c.Id); 
System.debug('Test caseStatus:' + c.status); 

Case c1 = new Case(); 
c1.Id = c.Id; 
c1.status = 'New'; 
update c1; 

System.debug('Test caseStatus1:' + c1.status); 

} 
}

Above example and further detail here: https://help.salesforce.com/apex/HTViewSolution?id=000181873&language=en_US

2
  • I think CasSe is a typo in the KB article; I also think that the type and url attributes are not relevant here when you explicitly deserialize into a Case object - they are more useful when deserializing into type = SObject or where you have related objects
    – cropredy
    Commented Nov 5, 2014 at 18:57
  • I thought the same when I first saw it but I have a working testmethod using it so it works for me.
    – Girbot
    Commented Nov 5, 2014 at 21:46
0

I'm not sure you can set the ClosedDate on a case object in the database. Everything I google says that it should be possible and the Knowledge Article seems to suggest it is possible by using JSON.deserialize(). But I have yet to find a working example.

Here's my proof that it doesn't work as advertised:

@isTest static void TestClosedDate() {
    Case c = new Case();
    c.Status = 'New';
    insert c;

    List<Case> cases = [select Id, ClosedDate from Case where Id = :c.Id];
    System.debug(JSON.serialize(cases[0]));

    String caseJson = JSON.serialize(c);

    // Modify status to Closed and add ClosedDate to JSON
    Datetime closedDate = Date.today().addDays(-1);
    String closedDateStr = closedDate.formatGMT('yyyy-MM-dd\'T\'HH:mm:ss.SSS+0000');
    caseJson = caseJson.replace('"New"', '"Closed","ClosedDate":"' + closedDateStr + '"');
    System.debug(caseJson);

    c = (Case) JSON.deserialize(caseJson, Case.class);
    System.debug(JSON.serialize(c)); // verify deserialization worked

    update c;

    cases = [select Id, ClosedDate from Case where Id = :c.Id];
    System.debug(JSON.serialize(cases[0]));
    System.assertEquals(closedDate, cases[0].ClosedDate);
}

This outputs something like:

{"attributes":{"type":"Case","url":"/services/data/v45.0/sobjects/Case/5001X00000346IIQAY"},"Id":"5001X00000346IIQAY"}
{"attributes":{"type":"Case","url":"/services/data/v45.0/sobjects/Case/5001X00000346IIQAY"},"Status":"Closed","ClosedDate":"2019-06-13T00:00:00.000+0000","Id":"5001X00000346IIQAY"}
{"attributes":{"type":"Case","url":"/services/data/v45.0/sobjects/Case/5001X00000346IIQAY"},"Status":"Closed","ClosedDate":"2019-06-13T00:00:00.000+0000","Id":"5001X00000346IIQAY"}
{"attributes":{"type":"Case","url":"/services/data/v45.0/sobjects/Case/5001X00000346IIQAY"},"Id":"5001X00000346IIQAY","ClosedDate":"2019-06-14T19:30:33.000+0000"}
Assertion Failed: Expected: 2019-06-13 00:00:00, Actual: 2019-06-14 19:30:33

The first three lines are as expected. Reading the database after the update reveals that the ClosedDate in the database was set to the current time instead of the deserialized time we used in our code.

To be fair, the Knowledge Article says:

You can create sObjects in memory with arbitrary CreatedDate values by using JSON.deserialize.

In memory, sure! As proven by line 3 of the output above.

But the update doesn't push what's in memory to the database, as shown on line 4. And the trigger code I'm trying to unit test really needs case objects in the database, not in memory.

If there are ways to do this, I'd love to learn about it. But for now, I'm going to assume it is simply not possible to create case objects in the database with a ClosedDate in the past.

3
  • Exactly, and why one should use selector patterns to query sobjects. This allows the test method to mock the selector results using the Json deserialize approach.
    – cropredy
    Commented Jun 15, 2019 at 22:00
  • The test above is simply a demonstration. My real world test is about testing a contact trigger that kicks in based on an update to a contact that has several cases assigned to it. The trigger is supposed to pick the newest case, and I wanted to verify this. I'd love to mock objects, but unfortunately, the way the trigger code is set up makes this impossible. Commented Jul 9, 2019 at 21:18
  • Ah, you can also look at the domain pattern on trailhead that will give you some ideas how to make triggers far more unit testable
    – cropredy
    Commented Jul 9, 2019 at 23:27

You must log in to answer this question.

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