global class BatchApexDemo implements 

    global integer recordProcessed = 0;
    global Database.QueryLocator start(Database.BatchableContext bc){
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(new string[]{'ayz@gmail.com'}); 
        mail.setSenderDisplayName('Salesforce Admin');
        mail.setSubject('Processing has Started...');
        mail.setPlainTextBody('Batch processing has just Started...');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[]{

        return Database.getQueryLocator(
            'SELECT Id, Name, BillingStreet, BillingCity,'+
            'BillingState, (SELECT MailingStreet, MailingCity, MailingState, FirstName, LastName FROM Contacts)'+
            'FROM Account'
    global void execute(Database.BatchableContext bc, List<Account> scope){
        List<Contact> con = new List<Contact>();
        for(Account acc : scope){
            for(Contact cont : acc.contacts){
                cont.MailingStreet = acc.BillingStreet;
                cont.MailingCity = acc.BillingCity;
                cont.MailingState = acc.BillingState;
                recordProcessed = recordProcessed + 1;
        update con;

    global void finish(Database.BatchableContext bc){
        Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
        email.setToAddresses(new String [] {
        email.setPlainTextBody('Batch processing has been Completed for '+recordProcessed+' Records...');
        email.setSubject('Batch processing has done...');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email});

Test class

public class BatchApexDemo_Test {

    private static void WhenStartCalled_ShouldNotFail(){
        BatchApexDemo job = new BatchApexDemo();



    private static void WhenFinishedCalled_ShouldNotFail(){
        BatchApexDemo job = new BatchApexDemo();


    private static void WhenExecuteCalled_ShouldUpdateTheContactRelatedToAccount(){

        BatchApexDemo bd = new BatchApexDemo();
        List<Account> acc = new List<Account>{
            new Account(
                        Name= 'Test Account', 
                        BillingStreet= 'Street No 12', 
                        BillingCity= 'Pune', 
                        BillingState= 'MH'
                insert acc;

        List<Contact> conn = new List<Contact>{
            new Contact(LastName= 'Test', 
                    FirstName= 'Test1', 
                    AccountId= acc[0].Id)
        insert conn;
        List<Account> accc = [SELECT Id, Name, BillingStreet, BillingCity, BillingState FROM Account WHERE Id =: conn[0].AccountId Limit : 1];
        System.debug('Accounts in Test Class = '+accc);
        conn[0].MailingStreet = accc[0].BillingStreet;
        conn[0].MailingCity = accc[0].BillingCity;
        conn[0].MailingState = accc[0].BillingState;
        System.debug('Contact in Test Class = '+conn);
        update conn;
        bd.execute(null, accc);


The above Test class Covers the 82% lines but I wanted to have 100%, can anyone please help.

1 Answer 1


This is because you call the execute method of your batch like a normal class.

To launch a batch you have to use the Database.executeBatch() method.

So for you test, you have to replace the line: bd.execute(null, accc); by:

Database.executeBatch(new BatchApexDemo());
  • Thanks Martin it works for me. Should I have to remove the test cases for start and finish methods from test class.
    – user46227
    Jun 19, 2017 at 12:30
  • No problem. Glad I could help. Yes you can remove them too. Jun 19, 2017 at 12:40

You must log in to answer this question.

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