I've come across some great threads on using Apex batch and schedule classes to overcome the 2K governor limits on reporting snapshots. For an example of the model I followed, see this article: How to overcome the 2000 row limit for analytic snapshot entry? I've successfully created a batch class that spoofs a reporting snapshot and have functionally tested it in a developer sandbox and now want to run it in production but am struggling with getting the test class, written.

My batch class:

global class SnapshotOpenCasesBatch implements Database.Batchable<sObject> 

    //Gather all the records I want to use in the execute method
    global Database.QueryLocator start(Database.BatchableContext BC) 
        return Database.getQueryLocator([SELECT ID, OwnerID, Name, Case_Type__c, Subtype__c, Status__c, Reason__c, Case_Age_Days__c, CreatedDate FROM Custom_Case__c WHERE Status__c in ('New', 'Work in Process', 'Escalated', 'Solution Proposed/Validation') ORDER BY CreatedDate ASC]); // Production source field is Created_Date__c

    global void execute(Database.BatchableContext BC, List<Custom_Case__c> openCases) 

            //for creating new Snapshot batch.
            List<Snapshot_Open_CASE__c> newSnapshot = new List<Snapshot_Open_CASE__c>();

            //create map collection to pair case owner ID and full name 
            Map<ID, String> userMap = new Map<ID, String>(); 

            //add all OwnerId values from openCases List to the set of userIds for query
            Set<ID> userIdSet = new Set<ID>();

            for (Custom_Case__c c : openCases) {

            //Go get all the User ID + name combos from the set of Ids created above
            List<User> userList = new List<User>([SELECT ID, Name FROM User WHERE ID in : userIdSet]);

            //Load userMap with the results of the query above
            for(User u : userList){
                userMap.put(u.id, u.Name);

            for (Custom_Case__c c : openCases) {
                Snapshot_Open_CASE__c snap = new Snapshot_Open_CASE__c();
                snap.CASE_ID__c = c.ID;
                snap.OwnerID__c = c.OwnerID;
                snap.Case_Number__c = c.Name;
                snap.Case_Type__c = c.Case_Type__c;
                snap.Subtype__c = c.Subtype__c;
                snap.Status__c = c.Status__c;
                snap.Reason__c = c.Reason__c;
                snap.Case_Age_Days__c = c.Case_Age_Days__c;
                snap.Created_Date__c = c.CreatedDate.date(); // Production source field is Created_Date__c // also convert datetime to date
                snap.Name = String.valueof(Date.today()); // Use execution date as unique id

                // add the user name
                snap.Owner_Full_Name__c = userMap.get(c.OwnerId);

                //load up the data for insert

            insert newSnapshot;

    global void finish(Database.BatchableContext BC) {
        system.debug('Batch Job is Complete');

My unit test class:


public class testSnapshotBatch { public static testMethod void testBatch() {

    // insert test data
    Snapshot_Open_CASE__c newSnapshot = new Snapshot_Open_CASE__c(
        CASE_ID__c = 'a0mE0000004oSiHIAU',
        OwnerID__c = '005E0000004e3aRIAQ',
        Case_Number__c = '114633',
        Case_Type__c = 'Machine/Component Failures',
        Subtype__c = 'Water/Cooler',
        Status__c = 'Solution Proposed/Validation',
        Reason__c = 'Quality Issue',
        Case_Age_Days__c = 257,
        Created_Date__c = date.parse('2/27/2014'), // Production source field is Created_Date__c // also convert datetime to date
        Name = String.valueof(Date.today()), // Use execution date as unique id
        Owner_Full_Name__c = 'Firstname Lastname');


    SnapshotOpenCasesBatch testBatch = new SnapshotOpenCasesBatch();

    ID batchprocessid = Database.executeBatch(testBatch,1);


    System.assert(batchprocessid != null);


} Most of the examples for unit tests are for triggers, and it's necessary to create test data for the trigger. In this scenario there is simply the SOQL SELECT query. What do I need to do to create the test data?

1 Answer 1


The same rules apply; you'll want to create exactly one record so that your code will run all the way through the loop, then verify after Test.stopTest() that a single snapshot record was created as a result.

  • thanks for your input. I updated the work in process that is the unit test class. How do I pass the one test record into the loop? Thanks. Nov 20, 2014 at 1:22
  • 1
    You have to insert a Custom_Case__c record that matches the criteria from the query in the start method, call Test.startTest, then call Database.executeBatch, and finally call Test.stopTest. Afterwards, query the table where the new record should have saved, and verify that a record was created.
    – sfdcfox
    Nov 20, 2014 at 3:14
  • thanks for the assistance and patience. I was able to pass the unit test with 100% code coverage. For an inexperienced individual as myself, unit testing demands a novel and different way of thinking. This elementary step was agonizingly slow, but I think I am learning. Thanks again for the tutoring. One last question, how do I handle different field names between test and production environments? Test has a field Created_Date__c and production has a corresponding field, CreatedDate. Do I change the field name in the batch class when I deploy through a change set? Thanks. Nov 21, 2014 at 18:26
  • @MatthewLTaylor You can't change it through a change set, which means you might have to use dynamic coding. Is there some reason why you can't use the same field in both environs?
    – sfdcfox
    Nov 21, 2014 at 18:34
  • upon closer inspection CreatedDate is a system field and is a default field on the object and is same in both environs. I won't have to hassle with dynamic coding. Thanks again! Nov 21, 2014 at 19:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.