0

I'm trying to search in enternet but no results.... So i haveing a batch that updates records (IT_Asset__c) if the FrstDayOfMnth__c = true. After that fires the trigger. The apex test class not covering the execute method without SeeAllData=true. here my execute method:

//Execute method
  global void execute (Database.BatchableContext BC, List<sobject> scope) {
List<IT_Asset__c> ITAList = new List<IT_Asset__c>();
List<IT_Asset__c> updtaedITAList = new List<IT_Asset__c>();
for (sObject objScope: scope) { 
    IT_Asset__c newObjScope = (IT_Asset__c)objScope ;
    newObjScope.FrstDayOfMnth__c = true;
    updtaedITAList.add(newObjScope);
    System.debug('Value of UpdatedITAList'+updtaedITAList);
} 
    if (updtaedITAList != null && updtaedITAList.size()>0) {
        Database.update(updtaedITAList); System.debug('List Size '+updtaedITAList.size());
    }
}

And here my test class:

@isTest(SeeAllData=false)
global class TestITAssetProcessingBatchClass {

public static testmethod void TestBatch(){
   ITAssetProcessingBatch c = new ITAssetProcessingBatch();
   c.query = 'Select id From IT_Asset__c Limit 200'; 

   Account acc = new Account();
   acc.Name = 'Test Account';
   insert acc;        

   List<IT_Asset__c> itass = new List<IT_Asset__c>();
    for(integer i = 0;  i < 25; i++){
        IT_Asset__c it = new IT_Asset__c(Account__c = acc.Id, FrstDayOfMnth__c = true, Quantity__c = 4);
        itass.add(it);
    }
    insert itass;

   Test.startTest();
   Database.executeBatch(c, 200);
   Test.stopTest();

   Integer listCont = [select COUNT() from IT_Asset__c where Account__c = :acc.id ];
   System.assertEquals(listCont, listCont);
}
}

Please point me, what i'm doing wrong?

5
  • 2
    What lines are left uncovered? Also, we seem to be missing a bunch of code in the Batchable class.... (start and finish methods, for example) Jun 1, 2016 at 15:38
  • Is there an error message you're receiving? Do you have any validation rules for IT_Asset__c? What do your debug statements show? I recommend you add debug statements to your test class and your batch class.
    – crmprogdev
    Jun 1, 2016 at 15:44
  • try changing order for test.stoptest(); and database.executeBatch(c,200); I know, this looks silly, but that will force salesforce to finish all DML and any processing before moving to Batch. I met similar problem where during Batch executions records were not in database yet.
    – Andrei.Z
    Jun 1, 2016 at 15:50
  • Are you getting any results from the query in batch, when the scope is empty(i.e, results are null from start method), the execute method will not be covered in tests.
    – Anurag
    Jun 1, 2016 at 15:52
  • undecovered is all code in //Execute method. I have no validation rules on IT_Assets__c. Whe i ran test no error is showing. I was trying to change order of 'test.stoptest();' and 'database.executeBatch(c,200);'
    – Viktor
    Jun 2, 2016 at 7:43

2 Answers 2

1

When setting up batch executions, I find it is often very helpful to add a number of System.assert() statements that verify that the data setup was correct before moving on to behavior assertions. I see after your Test.stopTest() you are doing a record count check, but that check is (a) occurs after your behavior testing, and (b) uses a different query than your actual batch job.

For this test, you can improve that setup check by changing the following:

Test.startTest();
Database.executeBatch(c, 200);
Test.stopTest();

to...

Test.startTest();

// Assert we have the correct number of records being returned by our batch query
System.assertEquals(25, Database.query(c.query).size(), 'We expected to find the same number of IT Asset records that we setup in the database.');

// Execute out batch
Database.executeBatch(c, 200);

// Force the batch to complete
Test.stopTest();

// Re-query for your data again and perform your behavior asserts here

I am not sure what the actual problem for you is, but adding this style of assert will not only help you troubleshoot now, but will help ensure that future changes to your org do not break the preconditions for this test.

2
  • Hi! Thanks for feedback! But this is doesn't work for me... I try to edit this line as you mention and below leave the two lines, but the code coverage is still 59%.
    – Viktor
    Jun 2, 2016 at 7:32
  • @Viktor, the purpose of that System.assert() is not to fix any bugs in your actual code. It will, however, make sure that your batch is actually executing on records during your test. You will need to do additional debugging of your code to figure out what is happening inside your execute method.
    – dsharrison
    Jun 2, 2016 at 16:37
0

So i realize that my test class is too complicated and copied. Now the coverage is 100% without SeeAllData=true:

@isTest
class TestITAssetProcessingBatchClass {

static testmethod void testBatch() {

   Account acc = new Account();
   acc.Name = 'Test Account';
   insert acc; 

List<IT_Asset__c> st=new List<IT_Asset__c>(); 
    for(integer i = 0;  i < 25; i++){
        IT_Asset__c it = new IT_Asset__c(Account__c = acc.Id, FrstDayOfMnth__c = true, Quantity__c = 4);
        st.add(it);
    }
    insert st;

    Database.BatchableContext bc;
    ITAssetProcessingBatch obj=new ITAssetProcessingBatch();
    obj.query = 'Select id From IT_Asset__c Where FrstDayOfMnth__c = true Limit 200';
    obj.start(BC);
    obj.execute(BC, st);
    obj.finish(BC);

    System.assertEquals(25, Database.query(obj.query).size() );
}
}

But now it show the error 'Attempt to de-reference a null object' in finish method and in the apex Batch process:

    //Below code will fetch the job Id
AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors, a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById, a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()];//get the job Id
System.debug('$$$ Jobid is'+BC.getJobId());

You must log in to answer this question.

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