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.


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 '17 at 12:30
  • No problem. Glad I could help. Yes you can remove them too. – Martin Lezer Jun 19 '17 at 12:40

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.