Unit testing code which has logic around the CreatedDate

Spring '16 Release Notes document a new system method supporting this:

Test.setCreatedDate(recordId, createdDatetime)

Sets CreatedDate for a test-context sObject.

This will definitely complement the loadData() and deserialize() techniques.

Account account = new Account(Name = 'Test');
insert account;

Datetime yesterday = Datetime.now().addDays(-1);
Test.setCreatedDate(account.Id, yesterday);

You can create sObjects in memory with arbitrary CreatedDate values by using JSON.deserialize. This doesn't enforce the normal read-only field attributes that prevent you from setting a createdDate value. However you can't commit arbitrary CreatedDate values to the database (or else it would be a serious security issue).

An example of doing so :

String caseJSON = '{"attributes":{"type":"Case","url":"/services/data/v25.0/sobjects/Case/500E0000002nH2fIAE"},"Id":"500E0000002nH2fIAE","CreatedDate":"2012-10-04T17:54:26.000+0000"}';
Case c = (Case) JSON.deserialize(caseJSON, Case.class );
System.debug(c.createdDate);

Note that I built the caseJSON string by creating a test case and serializing it, which is the easiest way to get JSON similar to what you want, then you can just tweak the values.

Edit: as of Spring16 you can use Test.setCreatedDate(Id,DateTime) to artificially set an SObject's CreatedDate in the database. JSON.deserialize is still handy for other read-only fields like LastModifiedDate though.


It isn't available now, but I'm reviewing the Winter 13 release notes and came across a new feature that sounds like it might work. I'm assuming this is what Rich alluded to in his comment above. The new feature is called Loading Test Data from Static Resources.

You'd load test data like so:

List<sObject> ls = Test.loadData(Account.sObjectType, 'myResource');

I'm assuming that you can also specify the CreatedDate in the static resources. There might still be a problem when testing triggers as this looks like it just creates the objects in memory and doesn't add them to the database. Perhaps you could isolate the code in a separate class from the trigger and unit test that class with the object in memory.

Tags:

Apex

Unit Test