Print this page

Setting system protected fields for test code coverage

Knowledge Article Number 000181873
There may be a use case in which, one needs to have Apex code that looks at system fields like CreatedDate, LastModifiedBy , etc. on a record and acts upon it. Setting system protected fields for test code coverage using normal DML operation from test class is not supported.
For example, the following line of code will not save throwing a save error: "Save error : Field is not writable : Case. CreatedDate" 
Case c = new Case(MyAccountId , Status='Open', CreatedDate = date.newinstance(2011, 4, 13).format()); 
Using API 24 or beyond, how can test classes be upgraded to latest version and achieve better code coverage by creating data that needs certain system fields set to certain values in test code? 
There are 2 ways in which you can set system protected fields for test code coverage:

a) Using Test.loadData()
b) Using JSON.deserialize()
1. Using Test.loadData. 
In this option you will need to create a .csv file and enter the necessary data in the .csv file. Once the csv file is ready, upload the csv file as a static resource. 
[Attaching a sample .csv file with the article to try the below example] 
a. Click Develop | Static Resources, and then New Static Resource. 
b. Name your static resource testCases. 
c. Choose the file you just created. 
d. Click Save. 
Then Call Test.loadData in a test method to populate the test case data. 
Code Example: 
private class caseUtil{ 
static testmethod void testLoadData(){ 
List<sObject> ls = Test.loadData(Case.sObjectType,'testCases'); 
Case c = (Case)ls[0]; 
System.assert(ls.size() == 1); 
String cStatus = c.Status; 
DateTime cDate = c.CreatedDate; 
System.debug('Case Id: ' + c.Id); 
System.debug('Case Status: ' + cStatus); 
System.debug('Case Date: ' + cDate); 
c.status = 'New'; 
update c; 
System.debug('Case status: ' + c.status); 
2. Using JSON.deserialize 
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. 
Code Example: 
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); 

Name Type Size

promote demote