3

I have written a batch class to mark a certain number of an object in a date range to be marked for review, and it is working when called on from a visualforce page, but it does not work when called in a test. Can anyone help me figure out what I'm doing wrong?

Batch class is:

global class batchAssignAudit implements Database.Batchable<sObject> {

    global Id auditUser{get; set;}
    global Date startDate{get; set;}
    global Date endDate{get; set;}
    global Integer percentageToCheck {get; set;}
    global Set<Object__c> objectsToAudit = new Set<Object__c>();
    global List<Object__c> objectsToAuditList = new List<Object__c>();
    global String query = 'SELECT ID, Needs_Audit__c FROM Object__c WHERE Status__c = \'Complete\' AND Captured_By__c = null AND Closed_Date_and_Time__c >= :startDate AND Closed_Date_and_Time__c <= :endDate';

    global batchAssignAudit() {

    }

    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext bc, List<Object__c> scope){
        while(objectsToAudit.size() < Math.floor(scope.size() * (Double.valueOf(percentageToCheck)/100))) {
            System.debug('while loop engaged');
            objectsToAudit.add(scope[Integer.valueof((Math.random() * scope.size()))]);
        }
        for(Object__c object : objectsToAudit){
            System.debug('for loop engaged');
            object.Captured_By__c = auditUser;
            object.Needs_Audit__c = true;
            objectsToAuditList.add(object);
        }
        System.debug(objectsToAuditList.size());
        update objectsToAuditList;
    }

    global void finish(Database.BatchableContext bc){
    }    
}

Test class is

@isTest
private class batchAssignAuditTest {

    @isTest static void batchAssignAuditTest() {
        List<Object__c> objectList = new List<Object__c>();

        User regUser = new User(
            //constructing user code
        );

        insert regUser;

        Account acc = new Account(
            Name = 'TestAccount',
            Phone = '7755559999'
        );

        insert acc;

        File__c file = new File__c(Account__c = acc.Id,
            First_Name__c = 'test',
            Last_Name__c = 'name2',
            Affix__c = 'jr',
            SSN__c = '123456789'
        );
        insert file;

        for(Integer i = 0; i < 100; i++) {
            Object__c v1 = new Object__c(File__c = file.Id,
                    Status__c = 'Complete',
                    Closed_Date_and_Time__c = Date.today()
                );
            objectList.add(
                v1
            );
        }
        insert objectList;

        Integer percentage = 10;
        Date startDate = Date.today().addDays(-5);
        Date endDate = Date.today().addDays(5);
        Integer batchSize = 1;

        batchAssignAudit audit = new batchAssignAudit();
        audit.auditUser = regUser.Id;
        audit.startDate = startDate;
        audit.endDate = endDate;
        audit.percentageToCheck = percentage;

        Test.startTest();

        if(Test.isRunningTest()) {
            Database.executeBatch(audit);
        }
    Test.stopTest();

    List<Object__c> testList = [SELECT ID FROM Object__c WHERE Needs_Audit__c = true];

    System.assertEquals(10, testList.size());
    }
}

Edit:

I should add the error I am getting when I run the test is

System.AssertException: Assertion Failed: Expected: 10, Actual: 0
1
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Adrian Larson
    Commented Aug 8, 2019 at 17:20

1 Answer 1

3

The problem is in the following expression.

Math.floor(scope.size() * (Double.valueOf(percentageToCheck)/100))

You can verify that this will always return 0 by executing the following piece of code in anonymous apex. I have just replaced the variables with expected values from your test class.

System.debug(Math.floor(100 * (Double.valueOf(10/100))));

However, the following expression returns 10 as expected.

System.debug(Math.floor(100 * (Double.valueOf(10/100.0))));

The reason for the issue is, 10/100 returns an integer, i.e. 0 and then Double.valueOf simply converts it to 0.0

By providing 100.0 as the value, the division implicitly is carried out using float numbers.

3
  • I'll change that, but the issue seems to be that the query isn't returning anything I think, because the execute is not running at all.
    – ccarlson
    Commented Aug 8, 2019 at 17:44
  • The above should be the root cause for that. When this expression returns 0, your while loop will not run. In turn, the subsequent for loop will also not run.
    – Aayush K
    Commented Aug 8, 2019 at 18:15
  • I changed it to 100.0, and am still having the same issue.
    – ccarlson
    Commented Aug 8, 2019 at 18:49

You must log in to answer this question.

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