I have a simple batch apex class, and when I write out the test, I cannot get the assertions to pass. Am I missing something?


global class batchADRtoNoUpdate implements Database.Batchable<sObject> {
    global Database.QueryLocator start(Database.BatchableContext BC) {
        String query = 'SELECT Id,Name,Can_be_worked_by_ADR__c,OwnerId 
                           FROM Account 
                           WHERE Days_Since_Reassignment_to_ADR__c > 0 AND
                                 Days_Since_Last_Activity__c > 30 AND
                                 Owner_Role__c = \'ADR\' AND
                                 Account_Status__c != \'Avoid Do Not Contact\' AND
                                 number_of_open_opps__c = 0 AND
                                 Last_Modified_by_Role__c != \'Marketing\'';
        return Database.getQueryLocator(query);

    global void execute(Database.BatchableContext BC, List<Account> scope) {
         for(Account a : scope)
             a.Can_be_worked_by_ADR__c = 'No';
             a.OwnerId = '005E0000004TStQ';             
         update scope;

    global void finish(Database.BatchableContext BC) {


private class batchADRtoNoUpdateTest {
    static testMethod void someAccounts() {
    //BEGIN: perform some setup steps...
        List<UserRole> roleId = ([ select id from userrole where name ='ADR']); //get role
        Profile prof = [SELECT Id FROM Profile WHERE Name = 'System Administrator']; //get a profile Id
        User user = new User(Alias = 'TDemo', UserRoleId = roleId[0].id, Email = 'greg@interactiveties.com', EmailEncodingKey = 'ISO-8859-1', FirstName = 'Demo', LanguageLocaleKey = 'en_US', LastName = 'User', LocaleSidKey = 'en_US', ProfileId = prof.Id, TimeZoneSidKey = 'America/Denver', Username = 'demo.test.user@interactiveties.com'); //new User details
        insert user;
        //create some testing accounts
        date assignDate = date.today().addDays(-4);
        date activityDate = date.today().addDays(-31);
        System.runAs(user) {
            List<Account> accounts = new List<Account>();
            Account account = new Account(OwnerId = user.Id, Name = 'Bedrock Consulting', 
                  website = 'bambam.bambam.com', 
                  Can_be_worked_by_ADR__c = 'Yes', 
                  Date_of_Reassignment__c = assignDate, 
                  Account_Status__c = 'Working');
            insert account; //insert the account list
            Task task = new Task(WhatId = account.Id, status = 'Complete', Subject = 'Test', Type = 'Email', ActivityDate = activityDate, OwnerId = user.id);
            insert task;
    //END: perform some setup steps...
        //run the batch process
        batchADRtoNoUpdate b = new batchADRtoNoUpdate();   
        //Parameters of ExecuteBatch(context,BatchSize)
        //validate that the account is assigned properly
        Account a = [SELECT Id,OwnerId, Can_be_worked_by_ADR__c FROM Account];
        User auser = [SELECT ID from User where Id =: a.OwnerId];
        User u = [SELECT Id from User where Id = '005E0000004TStQ'];
        System.assertEquals(a.Can_be_worked_by_ADR__c, 'No');
        System.assertEquals(auser.id, u.id);
  • does your start() query return any rows? check debug log. You have a very complex where clause so test data needs to be setup carefully – cropredy Feb 9 '15 at 22:16
  • I am wondering about that hard-coded ownerId. Are you sure that this exists during the test run? – FrankZ Feb 9 '15 at 22:33
  • @FrankZ Good question, is there a potentially better way of doing this? – Shaun Feb 9 '15 at 22:38
  • @crop1645 Thanks for that feedback, the logs do not show that any records were returned in the batch job. I'm going to look into existing workflow rules which could be changing the account before the test starts. – Shaun Feb 9 '15 at 22:50

I think your batch will be easier to test if you make make your query static and @TestVisible:

global class batchADRtoNoUpdate implements Database.Batchable<sObject> {
    @TestVisible static String query = 'SELECT Id FROM Account'; // WHERE x, y, z...

Then in your test you can override it:

class batchADRtoNoUpdateTest {
    static testMethod void testBatch() {
        batchADRtoNoUpdate.query = 'SELECT Id FROM Account';
        // if you are not using @SeeAllData, you may not even need a WHERE clause

In this way, you can test the results your query returns and the actions you perform on your scope independently. Speaking of which, you should probably add tests around what results your query returns.

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.