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
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.

  • 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 Aug 8 '19 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 Aug 8 '19 at 18:15
  • I changed it to 100.0, and am still having the same issue. – ccarlson Aug 8 '19 at 18:49

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.