0

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?

5
  • System.Json.deserialize() is a nice trick here Commented Dec 23, 2013 at 16:34
  • It is kind of a duplicate but I have to persist the objects so that the queries will work. It looks like I can create objects in memory but they still won't insert so that the queries can retrieve the data. Commented Dec 23, 2013 at 16:34
  • I understand that I could use JSON to create an object in memory with a specified CreatedDate. The problem is that I need multiple queries to work and I don't know how to get past the read only attribute on the CreatedDate for an object. I also understand that I can create branches around the queries when the system is in Test mode but the queries are still not tested fully and it is very important they work correctly. Commented Dec 23, 2013 at 16:56
  • Can you refactor the code so that you can test the logic without running the whole batch? That way you might not have to persist the objects.
    – Mike Chale
    Commented Dec 23, 2013 at 17:35
  • Mike, the problem is that the queries are important to selecting the records that need to be worked on. The feature is to find orphaned, or soon to be orphaned records that have been stored. One of the problems is that there is a Master record-link table-multiple child dependency and the first selection is based on the creation date. I may be able to change the amount of time something has to be old before it is deleted. I'll try that so instead of more than 24 hours, it will be seconds or milliseconds. Commented Dec 23, 2013 at 21:25

2 Answers 2

1

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.

2
  • 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
2

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
}
1
  • 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.
    – cropredy
    Commented Dec 23, 2013 at 18:52

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