+ Start a Discussion
Arpitha GowdaArpitha Gowda 

How do i write test class for the batch apex

Hello All

How do i write test class for below Batch apex class, 
 
global class Emailalertbatchclass implements Database.Batchable<sObject>, Schedulable, Database.Stateful {
    
    //Variable Section
    global FINAL String strQuery;
    global FINAL String leadid;
    global List<String> errorMessages = new List<String>();
    
    global Emailalertbatchclass() { 
        this.strQuery = getBatchQuery();
    }
    
    //Returns the Query String to Batch constructor to fetch right records.
    private String getBatchQuery() {
        String strQuery = 'SELECT Id,Name,Status,Email,owner.email,owner.name,ownerid,No_Enquiry_Email_Sent__c,Manager_Email__c FROM Lead where No_Enquiry_Email_Sent__c=false AND Status=\'Enquiry\' And (CreatedDate = YESTERDAY OR LastModifiedDate = YESTERDAY) limit 1';
        return strQuery;
    }
    
    //Batch Start method
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(strQuery);
    }
    
    //Batch Execute method calls findCostForWoD method
    global void execute(Database.BatchableContext BC, List<sObject> scopeList) {
        System.debug(LoggingLevel.INFO, '== scopeList size ==' + scopeList.size());
        
        List<Lead> ld = (List<Lead>) scopeList;
        List<Lead> updatedld = new List<Lead>();
        if(!ld.isEmpty()) { 
            List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
            for (Lead prod : ld)
            {               
                // Step 1: Create a new Email
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                
                // Step 2: Set list of people who should get the email
                String[] toAddresses = new String[] {prod.owner.Email,prod.Manager_Email__c,'chandra.s@proseraa.com'};
                    mail.setToAddresses(toAddresses);
                
                // Step 3: Set who the email is sent from
                mail.setReplyTo(prod.owner.Email);
                mail.setSenderDisplayName('No Activity on Leads for 24hrs');
                
                // (Optional) Set list of people who should be CC'ed
                List<String> ccTo = new List<String>();
                ccTo.add('manjunath.s@proseraa.com');
                mail.setCcAddresses(ccTo);
                
                // Step 4. Set email contents - you can use variables!
                mail.setSubject('No Activity on Lead for 24hrs');
                String body = 'Dear ' + prod.owner.name + ', <br><br>';
                body += 'This is to notify you that there is no activity done on the respective <b> Lead Name: ';
                body +=prod.Name+'</b>  please find the link below..<br><br>';
                body += 'link to file: https://moengage--proseraa.lightning.force.com/lightning/r/Lead/'+prod.id+'/view'+'<br><br><br> Thanks,<br>Moengage Team</body></html>';
                mail.setHtmlBody(body);
                
                // Step 5. Add your email to the master list
                mailList.add(mail);
                prod.No_Enquiry_Email_Sent__c = true;
                updatedld.add(prod);
                
            }
            if(!mailList.isEmpty()) {
                try{
                    Messaging.sendEmail(mailList);
                    update updatedld;
                }
                catch (Exception ex) {
                    errorMessages.add('Unable to send email to Tech: '+ ex.getStackTraceString());
                }
            }
        }
    }  
    
    //Batch Finish method for after execution of batch work
    global void finish(Database.BatchableContext BC) { 
        
    }
    
    //Method which schedules the ProductDownloadBatch
    global void execute(SchedulableContext sc) {        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
    }
}

 
Best Answer chosen by Arpitha Gowda
Dushyant srivastava 8Dushyant srivastava 8
remove the "Test.startTest()" from the 3rd line of the method and add that after "Test.setCreatedDate(ld.Id, yesterday);"

It will work fine then.
 
@isTest
public class EmailalertbatchclassTestclass
{
    static testMethod void testmethod1()
    {
        lead ld = new lead();
        ld.FirstName= 'test';
        ld.LastName='Test2';
        ld.status='Enquiry';
        ld.Company = 'fgfh';
        ld.Email = 'manjunath.s@proseraa.com';
        ld.Manager_Email__c = 'chandra.s@proseraa.com'  ;  
        Insert ld;  
        
        Datetime yesterday = Datetime.now().addDays(-1);
        Test.setCreatedDate(ld.Id, yesterday);
        
        Test.startTest();
        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
        
        Test.stopTest();
    }
}

See the above Class and try to modify your code accordinly.

All Answers

Arpitha GowdaArpitha Gowda
this is my test class with 19% coverage
 
@isTest
public class EmailalertbatchclassTestclass
{
    static testMethod void testmethod1()
    {
        lead ld = new lead();
        ld.FirstName= 'test';
        ld.LastName='Test2';
        ld.status='Enquiry';
        ld.Email = 'manjunath.s@proseraa.com';
        ld.Manager_Email__c = 'chandra.s@proseraa.com'  ;    
        Test.startTest();
        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
        
        Test.stopTest();
    }
}

 
Dushyant srivastava 8Dushyant srivastava 8
Hi Arpitha,

We have a test method named as setCreatedDate which needs 2 parameters. ID and Dateatime.
Please see the Code bellow.
 
@isTest
public class EmailalertbatchclassTestclass
{
    static testMethod void testmethod1()
    {
        lead ld = new lead();
        ld.FirstName= 'test';
        ld.LastName='Test2';
        ld.status='Enquiry';
        ld.Email = 'manjunath.s@proseraa.com';
        ld.Manager_Email__c = 'chandra.s@proseraa.com'  ;  

        Insert ld;  
        
        Datetime yesterday = Datetime.now().addDays(-1);
        Test.setCreatedDate(ld.Id, yesterday);
        
        Test.startTest();
        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
        
        Test.stopTest();
    }
}

 
Arpitha GowdaArpitha Gowda
@Dushyanth

it is not showing any Code Coverage, any suggestions??
Dushyant srivastava 8Dushyant srivastava 8
Hi Arpitha,

Please check if there is any error while running the test class. There might be a required field missing or something.
 
Dushyant srivastava 8Dushyant srivastava 8
I have compiled the same class just the comapny was the field which was required, So added that in Test Class.
User-added image
Arpitha GowdaArpitha Gowda
@Dushyanth

i tried modifying youtr code and got 28% coverage

i am getting an error in the test results - System.NoAccessException: Use Test.setCreatedDate() only before Test.startTest().
for Test.setCreatedDate(ld.Id, yesterday);

How do i correct it?
 
@isTest
public class EmailalertbatchclassTestclass
{
    static testMethod void testmethod1()
    {
        Id RecordTypeIdLead = Schema.SObjectType.Lead.getRecordTypeInfosByName().get('Lead Registration').getRecordTypeId();
        system.debug('RecordTypeIdLead '+RecordTypeIdLead);
         Test.startTest();
        List<Lead> Leadld = New List<Lead>();
        lead ld = new lead();
        ld.RecordTypeId = RecordTypeIdLead;
        ld.Company = 'Google';
        ld.FirstName= 'test';
        ld.LastName='Test2';
        ld.status='Enquiry';
        ld.Email = 'manjunath.s@proseraa.com';
        insert Leadld;

        Datetime yesterday = Datetime.now().addDays(-1);
        Test.setCreatedDate(ld.Id, yesterday);
        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
        
        Test.stopTest();
    }
    public static testMethod void testschedule() {
        Test.StartTest();
        Emailalertbatchclass sh1 = new Emailalertbatchclass();
        String sch = '0 00 01 * * ?'; 
        ID batchprocessid = Database.executeBatch(sh1);
        String jobId = system.schedule('Emailalertbatchclass', sch, sh1);
        System.assert(jobId != null);
        Test.stopTest(); 
    }
}
Dushyant srivastava 8Dushyant srivastava 8
remove the "Test.startTest()" from the 3rd line of the method and add that after "Test.setCreatedDate(ld.Id, yesterday);"

It will work fine then.
 
@isTest
public class EmailalertbatchclassTestclass
{
    static testMethod void testmethod1()
    {
        lead ld = new lead();
        ld.FirstName= 'test';
        ld.LastName='Test2';
        ld.status='Enquiry';
        ld.Company = 'fgfh';
        ld.Email = 'manjunath.s@proseraa.com';
        ld.Manager_Email__c = 'chandra.s@proseraa.com'  ;  
        Insert ld;  
        
        Datetime yesterday = Datetime.now().addDays(-1);
        Test.setCreatedDate(ld.Id, yesterday);
        
        Test.startTest();
        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
        
        Test.stopTest();
    }
}

See the above Class and try to modify your code accordinly.
This was selected as the best answer
Arpitha GowdaArpitha Gowda
@Dushyanth, Thank you very much for the help, my code coverage is 97%, i know i have not written the Correct test Class with the Best Pratices

below is my Updated Code
i forgot to Define the RecordTypeID

 
@isTest
public class EmailalertbatchclassTestclass
{
    static testMethod void testmethod1()
    {
        List<Lead> Leadld = new List<Lead>();
        Id RecordTypeIdLead = Schema.SObjectType.Lead.getRecordTypeInfosByName().get('Lead Registration').getRecordTypeId();
        system.debug('RecordTypeIdLead '+RecordTypeIdLead);
        lead ld = new lead();
        ld.FirstName= 'test';
        ld.RecordTypeId=RecordTypeIdLead;
        ld.LastName='Test2';
        ld.status='Enquiry';
        ld.Company = 'fgfh';
        ld.Email = 'manjunath.s@proseraa.com';
        ld.Manager_Email__c = 'chandra.s@proseraa.com';
        Insert ld;
        Leadld.add(ld); 
        
        Datetime yesterday = Datetime.now().addDays(-1);
        Test.setCreatedDate(ld.Id, yesterday);
        
        Test.startTest();
        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
        
        Test.stopTest();
    }
    public static testMethod void testschedule() {
        Test.StartTest();
        Emailalertbatchclass sh1 = new Emailalertbatchclass();
        String sch = '0 00 01 * * ?'; 
        ID batchprocessid = Database.executeBatch(sh1);
        String jobId = system.schedule('Emailalertbatchclass', sch, sh1);
        System.assert(jobId != null);
        Test.stopTest(); 
    }
}
Arpitha GowdaArpitha Gowda
@Dushyanth, sorry for asking, how do i write the test class for schedular class

This is my Schedular class
 
global class Scheduleerclassemailalert implements Schedulable
{
    global void execute(SchedulableContext SC) { 
         Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance); }
}

is is my test class
 
@istest
public class ScheduleerclassemailalertTestClass {
    
    test.startTest();
    ScheduleerclassemailalertTestClass sh1 = new ScheduleerclassemailalertTestClass();
    (String sch = '0 0 2 * * ?'); 
    system.schedule('Test Territory Check', sch, sh1); 
    test.stopTest();
    // add system asserts to check your expected behaviour
    
}