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
Muhammad Jawwad 16Muhammad Jawwad 16 

Batch Apex - How to write the test class?

Can anyone please help writing a test class?
global class LoanOfficerBatch implements Database.Batchable<sObject> {
    public String query = 'SELECT Loan_Officer_1a__c,Loan_Officer_1a__r.Email, ConvertedOpportunityId, Name, Phone,' 
                          +  'Status, Est_Re_Pull_Date__c, Realtor_Name__c ' 
                          +   ' FROM Lead'; 
    public EmailTemplate templateId = [Select Id,HtmlValue,Subject from EmailTemplate where name = 'LoanOfficerRecord' LIMIT 1];

    global Database.QueryLocator start(Database.BatchableContext bc) {

        query += ' WHERE CreatedDate = THIS_MONTH  AND Loan_Officer_1a__c != null';
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, list<Lead> allLeads) {
        
        
         
        List<String> convertedOppId = new List<String>();
         for(Lead l: allLeads){
	         convertedOppId.add(l.ConvertedOpportunityId); 
             }

         Map<Id, Opportunity> opptyMap = new Map<Id, Opportunity>();  
         for(Opportunity o : [SELECT Id,Name,Contact__r.Name,Contact__r.Phone,Starting_Credit_Score__c,Enrolled_On__c,Est_Re_Pull_Date__c,StageName FROM Opportunity WHERE Id IN: convertedOppId]){
	      opptyMap.put(o.Id, o);
          }
        
        
        
        Map<Id,List<Lead>> leadMap = new Map<Id,List<Lead>>();
        List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMEssage>();
        if(allLeads != null && allLeads.size() > 0){
            for(Lead l: allLeads){
                if(!leadMap.containsKey(l.Loan_Officer_1a__c)){
                    leadMap.put(l.Loan_Officer_1a__c, new List<lead>());
                }
                leadMap.get(l.Loan_Officer_1a__c).add(l);
            }
        }
        if(leadMap.keySet().size() > 0){
            Map<Id,Contact> officers = new Map<Id,Contact>([SELECT Id,Email,Name FROM Contact WHERE Id IN: leadMap.keySet()]);
            for(Id i: leadMap.keySet()){
                Contact con = officers.get(i);
                System.debug(con);
                if(String.isnOtBlank(con.Email)){
                    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    mail.setToAddresses(new String[]{con.EMail});
                    mail.setSubject(templateId.Subject);
                    String html = templateId.HtmlValue;
                    html = html.replace('||OfficerName||',con.Name);
                    String leadsTable = '<table cellpadding="3" cellspacing="3" width="100%" align="center" border="1" style="border-collapse:collapse;">'+
                        '<tr style="font-weight:bold;"><td>Name</td><td>Phone</td><td>Status</td><td>Est. Re Pull Date</td><td>Realtor Name</td></tr>';
                    
                    for(Lead l: leadMap.get(i))  
                    if(l.ConvertedOpportunityId==null)
                    {                    {
                        
                        
                        leadsTable += '<tr><td>'+l.Name+'</td>'+
                            '<td>'+l.Phone+'</td><td>'+l.Status+'</td>'+
                            '<td>'+l.Est_Re_Pull_Date__c+'</td><td>'+l.Realtor_Name__c+'</td></tr>';
                    }
                                               }
                    leadsTable += '</table>';
                    
                     String opptyTable = '<table cellpadding="3" cellspacing="3" width="100%" align="center" border="1" style="border-collapse:collapse;">'+
                        '<tr style="font-weight:bold;"><td>Name</td><td>Phone</td><td>Starting Credit Score</td><td>Enrolled On</td><td>Estimated Pull Date</td><td>StageName</td></tr>';
                    
                    for(Id idKey: opptyMap.keySet()){
                        Opportunity o = opptyMap.get(idKey);
                        
                        
                        opptyTable += '<tr><td>'+o.Contact__r.Name+'</td><td>'+o.Contact__r.Phone+'</td><td>'+o.Starting_Credit_Score__c+'</td><td>'+o.Enrolled_On__c+'</td>'
                            +'<td>'+o.Est_Re_Pull_Date__c+'</td><td>'+o.StageName+'</td></tr>';
                    }
                    opptyTable += '</table>';
                    html = html.replace('||Leads||',leadsTable);
                    html = html.replace('||Opportunity||',opptyTable);
                    html = html.replace('null',' ');
                    mail.setHTMLBody(html);
                    mails.add(mail);
                }
            }
        }
        if(mails.size() > 0){
            Messaging.sendEmail(mails);
        }
    }

    global void finish(Database.BatchableContext BC) {

    }
   
}
Best Answer chosen by Muhammad Jawwad 16
Raj VakatiRaj Vakati
use this
 
@isTest
private class LoanOfficerBatchTest {

static testMethod void exTest1(){
 Date startDate = Date.today().addDays(-2);
Contact c   = new Contact();
c.FirstName = 'Stephen';
c.LastName  = 'Curry';
c.Email     = 'stephcurry@gsw.com';
insert c;

Lead ls =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' ,Loan_Officer_1a__c =c.Id);
insert ls ;
Test.setCreatedDate(ls.Id, startDate);



Lead ls1 =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' );
insert ls1 ;
Test.setCreatedDate(ls1.Id, startDate);
Lead myLead = new Lead(LastName = 'Fry', Company='Fry And Sons');
 insert myLead;

Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(ls.id); 
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);

Database.LeadConvertResult lcr = Database.convertLead(lc);  
System.assert(lcr.isSuccess());


Database.LeadConvert lc1= new Database.LeadConvert(); 
lc1.setLeadId( ls1​​​.id);
lc1.setConvertedStatus(convertStatus.MasterLabel); 
Database.LeadConvertResult lcr1 = Database.convertLead(lc1);

Test.startTest();
LoanOfficerBatch lo=new LoanOfficerBatch();

Database.executeBatch(lo); 
Test.stopTest();
}
}

 

All Answers

JayantJayant
1. Setup the data.
2. Test.startTest()
3. Invoke the batch class.
4. Test.stopTest()

You're done. Just keep in mind that there should be exactly 1 batch to execute. If your batch class creates more than 1 batch, it would throw an error in test class.

For e.g.
Test.startTest();
MyBatchClass obj = new MyBatchClass();
Database.executeBatch(obj); 
Test.stopTest();

Just create the test data before these and ensure there would only be 1 batch created to be passed to execute() from start().
Muhammad Jawwad 16Muhammad Jawwad 16
@isTest
private class LoanOfficerBatchTest {

	static testMethod void exTest1(){
		 Date startDate = Date.today().addDays(-25);
    	Contact c   = new Contact();
       c.FirstName = 'Stephen';
       c.LastName  = 'Curry';
       c.Email     = 'stephcurry@gsw.com';
       insert c;
	   
		Lead ls =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' ,Loan_Officer_1a__c =c.Id);
		insert ls ;
		Test.setCreatedDate(ls.Id, startDate);
        

		
		Lead ls1 =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' );
		insert ls1 ;
		Test.setCreatedDate(ls1.Id, startDate);
        
		
		
		Test.startTest();
		Database.executeBatch(new LoanOfficerBatch ()); 
		Test.stopTest();
	}
}

I have create this one but the code coverage is only 12% can you please help.There is only 1 batch
JayantJayant
You need to create proper and enough data for all lines to be covered. You don't seem to be having any converted lead while your code is actually driven by converted leads.
Convert a few leads before executing your batch. You can convert using apex, link below -
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_convertLead.htm 
Muhammad Jawwad 16Muhammad Jawwad 16
if you don't mind can you please do it for me?
 
JayantJayant
Nope.
Just copy the code from the link and tweak it. Convert the lead ls that you are already creating and you may be done with it.
Muhammad Jawwad 16Muhammad Jawwad 16
@isTest
private class LoanOfficerBatchTest {

	static testMethod void exTest1(){
		 Date startDate = Date.today().addDays(-25);
    	Contact c   = new Contact();
       c.FirstName = 'Stephen';
       c.LastName  = 'Curry';
       c.Email     = 'stephcurry@gsw.com';
       insert c;
	   
		Lead ls =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' ,Loan_Officer_1a__c =c.Id);
		insert ls ;
		Test.setCreatedDate(ls.Id, startDate);
        

		
		Lead ls1 =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' );
		insert ls1 ;
		Test.setCreatedDate(ls1.Id, startDate);
        Lead myLead = new Lead(LastName = 'Fry', Company='Fry And Sons');
         insert myLead;

        Database.LeadConvert lc = new Database.LeadConvert();
        lc.setLeadId(myLead.id);

        LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
        lc.setConvertedStatus(convertStatus.MasterLabel);

        Database.LeadConvertResult lcr = Database.convertLead(lc);  
        System.assert(lcr.isSuccess());


		
		
		Test.startTest();
		Database.executeBatch(new LoanOfficerBatch ()); 
		Test.stopTest();
	}
}

I have copy and paste this but nothing could happen.
Raj VakatiRaj Vakati
Change your code as below
 
@isTest
private class LoanOfficerBatchTest {

	static testMethod void exTest1(){
		 Date startDate = Date.today().addDays(-25);
    	Contact c   = new Contact();
       c.FirstName = 'Stephen';
       c.LastName  = 'Curry';
       c.Email     = 'stephcurry@gsw.com';
       insert c;
	   
		Lead ls =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' ,Loan_Officer_1a__c =c.Id);
		insert ls ;
		Test.setCreatedDate(ls.Id, startDate);
        

		
		Lead ls1 =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' );
		insert ls1 ;
		Test.setCreatedDate(ls1.Id, startDate);
        Lead myLead = new Lead(LastName = 'Fry', Company='Fry And Sons');
         insert myLead;

        Database.LeadConvert lc = new Database.LeadConvert();
        lc.setLeadId(ls.id);
		LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
        lc.setConvertedStatus(convertStatus.MasterLabel);

        Database.LeadConvertResult lcr = Database.convertLead(lc);  
        System.assert(lcr.isSuccess());


		Database.LeadConvert lc1= new Database.LeadConvert(); 
lc1.setLeadId(ls1​​​.id);
lc1.setConvertedStatus(convertStatus.MasterLabel); 
Database.LeadConvertResult lcr1 = Database.convertLead(lc1);​​​​​​​
		
		Test.startTest();
		LoanOfficerBatch lo=new LoanOfficerBatch();
		lo.objName ='Lead';
		Database.executeBatch(lo); 
		Test.stopTest();
	}
}

 
Muhammad Jawwad 16Muhammad Jawwad 16
in line no 40 objname does not exist i have changed the object name to query test class was run but the code coverage is only 10 %
Raj VakatiRaj Vakati
My bad 

use this
 
@isTest
private class LoanOfficerBatchTest {

	static testMethod void exTest1(){
		 Date startDate = Date.today().addDays(-25);
    	Contact c   = new Contact();
       c.FirstName = 'Stephen';
       c.LastName  = 'Curry';
       c.Email     = 'stephcurry@gsw.com';
       insert c;
	   
		Lead ls =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' ,Loan_Officer_1a__c =c.Id);
		insert ls ;
		Test.setCreatedDate(ls.Id, startDate);
        

		
		Lead ls1 =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' );
		insert ls1 ;
		Test.setCreatedDate(ls1.Id, startDate);
        Lead myLead = new Lead(LastName = 'Fry', Company='Fry And Sons');
         insert myLead;

       <i><b> Database.LeadConvert lc = new Database.LeadConvert();
        lc.setLeadId(ls.id);</b></i>
		LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
        lc.setConvertedStatus(convertStatus.MasterLabel);

        Database.LeadConvertResult lcr = Database.convertLead(lc);  
        System.assert(lcr.isSuccess());


	<b>	<i>Database.LeadConvert lc1= new Database.LeadConvert(); 
lc1.setLeadId(</i>ls1​​​<i>.id);
</i>lc1.setConvertedStatus(convertStatus.MasterLabel); 
Database.LeadConvertResult lcr1 = Database.convertLead(lc1);
		</b>
		Test.startTest();
		LoanOfficerBatch lo=new LoanOfficerBatch();
	 
		Database.executeBatch(lo); 
		Test.stopTest();
	}
}

​​​​​​​
Raj VakatiRaj Vakati
can u give me which lines are not covering 
Muhammad Jawwad 16Muhammad Jawwad 16

User-added image

code coverage is only 12%

Raj VakatiRaj Vakati
use this
 
@isTest
private class LoanOfficerBatchTest {

static testMethod void exTest1(){
 Date startDate = Date.today().addDays(-2);
Contact c   = new Contact();
c.FirstName = 'Stephen';
c.LastName  = 'Curry';
c.Email     = 'stephcurry@gsw.com';
insert c;

Lead ls =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' ,Loan_Officer_1a__c =c.Id);
insert ls ;
Test.setCreatedDate(ls.Id, startDate);



Lead ls1 =new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open' );
insert ls1 ;
Test.setCreatedDate(ls1.Id, startDate);
Lead myLead = new Lead(LastName = 'Fry', Company='Fry And Sons');
 insert myLead;

Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(ls.id); 
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);

Database.LeadConvertResult lcr = Database.convertLead(lc);  
System.assert(lcr.isSuccess());


Database.LeadConvert lc1= new Database.LeadConvert(); 
lc1.setLeadId( ls1​​​.id);
lc1.setConvertedStatus(convertStatus.MasterLabel); 
Database.LeadConvertResult lcr1 = Database.convertLead(lc1);

Test.startTest();
LoanOfficerBatch lo=new LoanOfficerBatch();

Database.executeBatch(lo); 
Test.stopTest();
}
}

 
This was selected as the best answer
Raj VakatiRaj Vakati
wokring ?
Muhammad Jawwad 16Muhammad Jawwad 16
its working with 94% code coverage Thank you so much