+ Start a Discussion
Gaurav AgnihotriGaurav Agnihotri 

Test class for batch insert shows 0 code coverage

Gurus, 
I have test class for a batch insert and it shows 0 code coverage. I am not sure what I am doing wrong.
Below is the class:
global class batchPPBInsert implements Database.Batchable<sObject>,Database.Stateful
{
  global Integer sizePPB = 0;
    global Database.QueryLocator start(Database.BatchableContext BCPPBI)
    {
        string operation;
        operation='Insert';
        String query = 'SELECT Currency_Code__c,Currency_Number__c,Dealer_Price__c,IsDeleted,Item__c,Name,OwnerId,Price_Scheme_Location__c,Territory__c FROM Pelco_Price_Book_Stage__c';
        query=query +' WHERE Operation_Type__c = \'' + String.escapeSingleQuotes(operation) + '\'';
        return Database.getQueryLocator(query);
    }
   
    global void execute(Database.BatchableContext BCPPBI, List<Pelco_Price_Book_Stage__c> scope)
    {
        List<Pelco_Price_Book__c> lstPPB = new List <Pelco_Price_Book__c>(); 
        for(Pelco_Price_Book_Stage__c PPBStg : scope)
         {
           Pelco_Price_Book__c PPB = new Pelco_Price_Book__c();
           PPB.Currency_Code__c=PPBStg.Currency_Code__c;
           PPB.Currency_Number__c=PPBStg.Currency_Number__c;
           PPB.Dealer_Price__c=PPBStg.Dealer_Price__c;
           //PPB.IsDeleted=PPBStg.IsDeleted;
           PPB.Item__c=PPBStg.Item__c;
           PPB.Name=PPBStg.Name;
           PPB.Price_Scheme_Location__c=PPBStg.Price_Scheme_Location__c;            
           PPB.Territory__c=PPBStg.Territory__c;
           lstPPB.add(PPB);  
           
         }
        sizePPB += scope.size(); 
        system.debug('SizePPB='+SizePPB);
        insert(lstPPB);
        delete(scope);
    }   
    global void finish(Database.BatchableContext BCPPBI)
    {
        String email;
        //email='gaurav.agnihotri@schneider-electric.com';
        AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id =:BCPPBI.getJobId()];
        //SizePPB= [SELECT Count() from Pelco_Price_Book_Stage__c WHERE Operation_Type__c = 'Insert'];
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
		mail.setToAddresses(new String[] {'gaurav.agnihotri@schneider-electric.com','nhombal@pelco.com','dfisher@schneider-electric.com','ron.adolph@schneider-electric.com'});
		mail.setReplyTo('gaurav.agnihotri@schneider-electric.com');
		mail.setSenderDisplayName('Batch Processing');
		mail.setSubject('Batch Process Completed for insert on Pelco Price book');
        if (a.Status == 'Completed')
		mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +' batches of batch size '+ SizePPB+ ' with '+a.NumberOfErrors + ' failures.');		
        if (a.Status == 'Failed')
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +' batches of batch size '+ SizePPB+ ' with '+a.NumberOfErrors + ' failures. Failure Message: '+a.ExtendedStatus);

        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
}

 the test class:
@istest
private class TestbatchPPBInsert {
    static testMethod void batchPPBMethod1(){
        /************************/
        //Insert Pelco Price Book
        /************************/
            Pelco_Price_Book_Stage__c PPB= new Pelco_Price_Book_Stage__c();
            PPB.Currency_Code__c='CAD';
            PPB.Currency_Number__c='1';
            PPB.Dealer_Price__c=276.3;
            //PPB.Id='a03g0000008K0KGAA0';
            PPB.Item__c='EH16-2PMTS';
            PPB.Name='a03g0000008K0KG';
            //PPB.Operation_Date_and_Time__c=2015-08-21T19:51:21.000Z;
            PPB.Operation_Type__c='Insert';
            PPB.Price_Scheme_Location__c='E7';
            PPB.Territory__c=17;
            insert PPB;
          system.debug('PPBId='+PPB.id);
        batchPPBInsert b3= new batchPPBInsert();
		database.executeBatch(b3);
    }
}

Not sure what I am doing wrong

-Gaurva
 
Best Answer chosen by Gaurav Agnihotri
Amit Chaudhary 8Amit Chaudhary 8
Testing Batch Apex

When testing your batch Apex, you can test only one execution of the execute method. Use the scope parameter of theexecuteBatch method to limit the number of records passed into the execute method to ensure that you aren’t running into governor limits.

The executeBatch method starts an asynchronous process. This means that when you test batch Apex, you must make certain that the batch job is finished before testing against the results. Use the Test methods startTest and stopTest around theexecuteBatch method to ensure that it finishes before continuing your test. All asynchronous calls made after the startTestmethod are collected by the system. When stopTest is executed, all asynchronous processes are run synchronouslyIf you don’t include the executeBatch method within the startTest and stopTest methods,the batch job executes at the end of your test method for Apex saved using Salesforce API version 25.0 and later, but not in earlier versions.

Starting with Apex saved using Salesforce API version 22.0, exceptions that occur during the execution of a batch Apex job that is invoked by a test method are now passed to the calling test method, and as a result, causes the test method to fail. If you want to handle exceptions in the test method, enclose the code in try and catch statements. Place the catch block after the stopTestmethod. However, with Apex saved using Salesforce API version 21.0 and earlier, such exceptions don’t get passed to the test method and don’t cause test methods to fail.

Please let us know if this will help u

All Answers

William LópezWilliam López
Hello Gaurva, I think you are only missing the start and Stop Methods.

Check this link:
https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_batch_2.htm

The call to Database.executeBatch is included within the Test.startTest and Test.stopTest block. This is necessary for the batch job to run in a test method. The job executes after the call to Test.stopTest. Any asynchronous code included within Test.startTest and Test.stopTest gets executed synchronously after Test.stopTest.

So the code change need will be:
 
Test.StartTest();

   batchPPBInsert b3= new batchPPBInsert();
  database.executeBatch(b3);

 Test.StopTest();

Regards,

​Don't forget to mark your thread as 'SOLVED' with the answer that best helps you.   
 
Gaurav AgnihotriGaurav Agnihotri
Hi William, 
Even after including Test.StartTest() and Test.StopTest(), there is still ZERO code coverage.
Any suggestion?
Gaurav AgnihotriGaurav Agnihotri
when I "run all"  test,then I get 100% code coverage. Otherwise, when I just run test class, I get 0

I am not sure why
Amit Chaudhary 8Amit Chaudhary 8
Please try below test class
@istest
private class TestbatchPPBInsert 
{
    static testMethod void batchPPBMethod1()
	{
            Pelco_Price_Book_Stage__c PPB= new Pelco_Price_Book_Stage__c();
            PPB.Currency_Code__c='CAD';
            PPB.Currency_Number__c='1';
            PPB.Dealer_Price__c=276.3;
            PPB.Item__c='EH16-2PMTS';
            PPB.Name='a03g0000008K0KG';
            PPB.Operation_Type__c='Insert';
            PPB.Price_Scheme_Location__c='E7';
            PPB.Territory__c=17;
            insert PPB;
			
			system.debug('PPBId='+PPB.id);
			system.debug('PPB.Operation_Type__c------>'+PPB.PPB.Operation_Type__c);
			
			Test.StartTest();
				batchPPBInsert  b3= new batchPPBInsert ();
				database.executeBatch(b3);
			Test.StartTest();
			
    }
    static testMethod void batchPPBMethod2()
	{
            Pelco_Price_Book_Stage__c PPB= new Pelco_Price_Book_Stage__c();
            PPB.Currency_Code__c='CAD';
            PPB.Currency_Number__c='1';
            PPB.Dealer_Price__c=276.3;
            PPB.Item__c='EH16-2PMTS';
            PPB.Name='a03g0000008K0KG';
            PPB.Operation_Type__c='Insert';
            PPB.Price_Scheme_Location__c='E7';
            PPB.Territory__c=17;
            insert PPB;

            PPB.Operation_Type__c='Insert';
			update 	PPB
			system.debug('PPBId='+PPB.id);
			system.debug('PPB.Operation_Type__c------>'+PPB.PPB.Operation_Type__c);
			
			Test.StartTest();
				batchPPBInsert  b3= new batchPPBInsert ();
				database.executeBatch(b3);
			Test.StartTest();
			
    }
}

 
Chandra Sekhar CH N VChandra Sekhar CH N V
I did get coverage when I tried your code for another object but didn't cover execute() in the batch class. But after including another method call in test class I got 96% coverge. Try adding the below line after executebatch() statement:
 
b3.execute(null, new list<your object> {PPB});





 
Gaurav AgnihotriGaurav Agnihotri
Thanks, Amit and Chandra...

I was able to figure out and the test seems to work fine when run individually.
I have to check the option 
Test "Always run asynchronously"

However, I do not understand why
Amit Chaudhary 8Amit Chaudhary 8
Testing Batch Apex

When testing your batch Apex, you can test only one execution of the execute method. Use the scope parameter of theexecuteBatch method to limit the number of records passed into the execute method to ensure that you aren’t running into governor limits.

The executeBatch method starts an asynchronous process. This means that when you test batch Apex, you must make certain that the batch job is finished before testing against the results. Use the Test methods startTest and stopTest around theexecuteBatch method to ensure that it finishes before continuing your test. All asynchronous calls made after the startTestmethod are collected by the system. When stopTest is executed, all asynchronous processes are run synchronouslyIf you don’t include the executeBatch method within the startTest and stopTest methods,the batch job executes at the end of your test method for Apex saved using Salesforce API version 25.0 and later, but not in earlier versions.

Starting with Apex saved using Salesforce API version 22.0, exceptions that occur during the execution of a batch Apex job that is invoked by a test method are now passed to the calling test method, and as a result, causes the test method to fail. If you want to handle exceptions in the test method, enclose the code in try and catch statements. Place the catch block after the stopTestmethod. However, with Apex saved using Salesforce API version 21.0 and earlier, such exceptions don’t get passed to the test method and don’t cause test methods to fail.

Please let us know if this will help u
This was selected as the best answer