I have a batch process that deletes records. The problem is that it has become more complex so there is some logic to get multiple lists of objects. The problem I have is that the Created data must be in the past and when creating test objects, they get the current date. How do I create test objects with past dates in order to get proper test coverage?
2 Answers
You may be able to convince Salesforce to enable the ability to set the audit fields as per the documentation described here. This applies to the indicated standard objects and custom once enabled.
If you import data into Salesforce and need to set the value for an audit field, contact salesforce.com. Once salesforce.com enables this capability for your organization, you can set audit field values
I would assume with this enabled, you can not only set the audit fields such as CreatedDate but also then insert such records via DML. If you explain you want to do this in a test context they may also be more relaxed about enabling it for this use case. Though keep in mind this will need to be enabled for all orgs where your tests run, so may not be an ideal if this is the case.
-
OK so here's the big problem. What I need to test are some select statements and a code block in a Schedulable class. Since this runs asynchronous, when the scheduled job runs, the test environment has already deleted the records I created for testing. Is there a way to get the scheduled code to execute before the test code finishes and the test data is removed? The problem is that the test code coverage is low and I can't tell if the queries are working as designed without running live. Commented Dec 24, 2013 at 15:17
-
Salesforce has specific support in its Apex test framework for testing Schedulable classes, take a look at this, salesforce.com/us/developer/docs/apexcode/Content/…, so any test data you setup will be visible to the select statements. Commented Dec 24, 2013 at 15:22
The usual way to handle this logic is to write a logic branch in your batch class' constructor, or provide a testing query to work against. One possible scenario would look like this:
global class PerformCleanup implements Database.Batchable<SOBject> {
DateTime sinceWhen;
global PerformCleanup() {
this(DateTime.now());
}
global PerformCleanup(DateTime sinceWhen) {
this.sinceWhen = sinceWhen;
}
global Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator([SELECT ... FROM ... WHERE CreatedDate <= :sinceWhen]);
}
// Rest of class here
}
-
sfdcfox's approach has other benefits - allows you to construct tests where you want a specific date to be 'today' - such as testing auto-renewals where you want to verify your date arithmetic logic works on leap years, Feb 28th, etc.– cropredyCommented Dec 23, 2013 at 18:52
System.Json.deserialize()
is a nice trick here