function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Avinash RaviAvinash Ravi 

Need help with test class for batch apex

global class sendEmailtoVolntr implements schedulable,Database.Batchable<sObject>,Database.Stateful
{
    global String Query = null;

    global sendEmailtoVolntr (){
  
       Query='Select Id,Name,For_Centre__c,For_Date__c,Leap_Centre__c,Leap_Centre__r.Name,Send_Email__c,Short_Description__c,Uploaded_By__c from Leap_Weekly_Curriculum__c where Send_Email__c = FALSE and For_Date__c >= TODAY';
   
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator(Query);
    }
    
    global void execute(SchedulableContext SC){
        sendEmailtoVolntr sendEmail= new sendEmailtoVolntr ();
        database.executebatch(sendEmail,1);
     }
    
    global void execute(Database.BatchableContext BC, List<sObject> scope){
    
        List<Attachment> attachments = new List<Attachment> ();
        Map<Id,Attachment> attachmentId = new Map<Id,Attachment> ();
        Set<Id> LeapIds = new Set<Id> ();
        List<Leap_Weekly_Curriculum__c> leapCurrilist = new List<Leap_Weekly_Curriculum__c> ();
        List<Leap_Weekly_Curriculum__c> updateLeapList = new List<Leap_Weekly_Curriculum__c> ();
    
        for(sObject so : scope){ 
    
            Leap_Weekly_Curriculum__c leapCurri= (Leap_Weekly_Curriculum__c)so;
            LeapIds.add(leapcurri.Id);
            leapCurrilist.add(leapCurri);
           } 
        attachments = [SELECT Id,ParentId, Name, Body, ContentType FROM Attachment WHERE Parentid IN :LeapIds];
          //Assuming that there will be only one attachment for each Leap Curriculum record           
        for(Attachment att : attachments)
        {
            attachmentId.put(att.ParentId,att);
        }
        attachments.clear();
        
        for(Leap_Weekly_Curriculum__c LWC: leapCurrilist)
        {
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            List<Messaging.SingleEmailMessage> theEmails = new List<Messaging.SingleEmailMessage> ();
            List<Messaging.EmailFileAttachment> emailAttachments = new List<Messaging.EmailFileAttachment>();
            Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
            List<String> toAddresses = new List<String> ();
            String emailErrorReport = null;
            
            for(Volunteers__c vol: [Select Email__c from Volunteers__c WHERE Centre_Allocation__c includes(:LWC.Leap_Centre__r.Name)])
            toAddresses.add(vol.Email__c);
            //List<Volunteers__c> volListTeamp = [Select Email__c from Volunteers__c WHERE Centre_Allocation__c includes(:LWC.Leap_Centre__r.Name)];
            system.debug(toAddresses);
    
            efa.setFileName(attachmentId.get(LWC.Id).Name);
            efa.setBody(attachmentId.get(LWC.Id).Body);
            efa.setContentType(attachmentId.get(LWC.Id).ContentType);
            emailAttachments.add(efa);
            
            if(emailAttachments.size() > 0)
            {
                email.setToAddresses(toAddresses);
                email.setSubject('test');
                email.setPlainTextBody('For Leap Curriculum : ID -  ' + LWC.Id + ' Name - ' + LWC.Name + ' Short Description - ' + LWC.Short_Description__c + '.');
                email.setFileAttachments(emailAttachments);
                theEmails.add(email);
            }
            
            if(theEmails.size() > 0)
            {
                
                Messaging.SendEmailResult[] results = Messaging.sendEmail(theEmails,false);
                Messaging.SendEmailError[] errors = new List<Messaging.SendEmailError>();
                
                for( Messaging.SendEmailResult currentResult : results ) 
                {
                    errors = currentResult.getErrors();
                    if( null != errors ) 
                    {
                        for( Messaging.SendEmailError currentError : errors ) 
                        {
                            emailErrorReport = emailErrorReport + '(' +  currentError.getStatusCode() + ')' + currentError.getMessage() + '\r' ;
                        }
                    }
                }
    
                system.debug('error : ' + emailErrorReport);

             }

            System.debug('HEAP_SIZE Used:'+ Limits.getHeapSize()); 
            
            if(emailErrorReport != null){
                break;
            }
            else
            {
                LWC.send_EMail__c = TRUE;
                updateLeapList.add(LWC);  
            }
            
            if(updateLeapList.size()>0)
            update updateLeapList;
            
            if(emailErrorReport != null){
                System.abortJob(BC.getJobId()); 
                List<sObject> so = scope;
                Leap_Weekly_Curriculum__c lwcr= (Leap_Weekly_Curriculum__c )so[0];          
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                String[] toAddresseser = new String[] {'rahmeshms@outlook.com'};
                mail.setToAddresses(toAddresseser);
                mail.setSubject('Email Job is aborted'); 
                mail.setPlainTextBody('The send email job is aborted due to Leap Curriculum : '+lwcr.Name+' '+lwcr.Short_Description__c+ ' '+lwcr.Id+ 'Please check the error report and take action accordingly.\n\n\t Error - '+emailErrorReport);
                Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
            }
       } 
       
   }
global void finish(Database.BatchableContext BC){

    }


    
        }

I'm new to development and need help writing a test class for this batch class. I have no idea where to start or end. Please help out.

Thanks,
Avinash
Best Answer chosen by Avinash Ravi
TintuBabuTintuBabu
Hi,
For any test class first thing we need to do is to insert all database records needed. So first inser records for objects like Leap_Weekly_Curriculum__c you have referred in this batch . Then simply call batch in between   Test.startTest(); and Test.stopTest(); in order to reset limits.

Here is an example from salesforce documentation.

@isTest
private class TestCleanUpBatchClass {

    static testmethod void test() {
        // The query used by the batch job.
        String query = 'SELECT Id,CreatedDate FROM Merchandise__c ' +
                   'WHERE Id NOT IN (SELECT Merchandise__c FROM Line_Item__c)';

       // Create some test merchandise items to be deleted
       //   by the batch job.
       Merchandise__c[] ml = new List<Merchandise__c>();
       for (Integer i=0;i<10;i++) {
           Merchandise__c m = new Merchandise__c(
               Name='Merchandise ' + i,
               Description__c='Some description',
               Price__c=2,
               Total_Inventory__c=100);
           ml.add(m);
       }
       insert ml;

       Test.startTest();
       CleanUpRecords c = new CleanUpRecords(query);
       Database.executeBatch(c);
       Test.stopTest();

       // Verify merchandise items got deleted
       Integer i = [SELECT COUNT() FROM Merchandise__c];
       System.assertEquals(i, 0);
    }
}
 

All Answers

TintuBabuTintuBabu
Hi,
For any test class first thing we need to do is to insert all database records needed. So first inser records for objects like Leap_Weekly_Curriculum__c you have referred in this batch . Then simply call batch in between   Test.startTest(); and Test.stopTest(); in order to reset limits.

Here is an example from salesforce documentation.

@isTest
private class TestCleanUpBatchClass {

    static testmethod void test() {
        // The query used by the batch job.
        String query = 'SELECT Id,CreatedDate FROM Merchandise__c ' +
                   'WHERE Id NOT IN (SELECT Merchandise__c FROM Line_Item__c)';

       // Create some test merchandise items to be deleted
       //   by the batch job.
       Merchandise__c[] ml = new List<Merchandise__c>();
       for (Integer i=0;i<10;i++) {
           Merchandise__c m = new Merchandise__c(
               Name='Merchandise ' + i,
               Description__c='Some description',
               Price__c=2,
               Total_Inventory__c=100);
           ml.add(m);
       }
       insert ml;

       Test.startTest();
       CleanUpRecords c = new CleanUpRecords(query);
       Database.executeBatch(c);
       Test.stopTest();

       // Verify merchandise items got deleted
       Integer i = [SELECT COUNT() FROM Merchandise__c];
       System.assertEquals(i, 0);
    }
}
 
This was selected as the best answer
Avinash RaviAvinash Ravi
This is the test class I've written and it says::: Compile Error: Constructor not defined: [sendEmailtoVolntr].<Constructor>(String) at line 37 column 30
 
@isTest
public with sharing class Attachmentstest{
public static testmethod void Attachmentstest()
{

        Leap_Weekly_Curriculum__c record = new Leap_Weekly_Curriculum__c();
        Attachment attachment1 = new Attachment();
        Leap_Centre__c lcr = new Leap_Centre__c();
        
       lcr.Name = 'Anaikkum Karangal';
       lcr.Location__c = 'test location';
       lcr.Primary_Representative__c = 'Avinash';
       lcr.Primary_Rep_s_Mobile__c = '9176473115';
       lcr.Primary_Rep_s_Email__c = 'asd@asd.com';
       
       insert lcr;
       
       record.Short_Description__c = 'test record';
       record.For_Centre__c = 'Anaikkum Karangal';
       record.For_Date__c = Date.Today();
       record.Uploaded_By__c = 'Avinash'; 
       record.Leap_Centre__c = lcr.Id;
     
        // Insert the record
        insert record;
        system.debug(record);
        
        // Insert Attachments;
        attachment1.Name='Unit Test Attachment';
        attachment1.ParentId = record.Id;
        attachment1.body=Blob.valueOf('Unit Test Attachment Body');
        insert attachment1;
        
 String Query='Select Id,Name,For_Centre__c,For_Date__c,Leap_Centre__c,Leap_Centre__r.Name,Send_Email__c,Short_Description__c,Uploaded_By__c from Leap_Weekly_Curriculum__c where Send_Email__c = FALSE and For_Date__c >= TODAY';
 
       Test.startTest();
       sendEmailtoVolntr c = new sendEmailtoVolntr(query);
       Database.executeBatch(c);
       Test.stopTest();   
 
 }
     
 }

Please help out!

 
TintuBabuTintuBabu
Hi
The constructor you defined is not taking any parameters so just do
sendEmailtoVolntr c = new sendEmailtoVolntr();
Database.executeBatch(c);
Avinash RaviAvinash Ravi
Hi Babu,

Thanks a lot for your elaborate responses. I'm not able to cover lines 106 - 119 on the test class. Not sure how I can bring out an error sending the email to go into that part of code. 

Any ideas? Get what I mean?