+ Start a Discussion
SAHG-SFDCSAHG-SFDC 

Trying to complete a challenge on trail head -Create an Apex class that implements the Database.Batchable interface to update all Lead records in the org with a specific LeadSource. Write unit tests that achieve 100% code coverage for the class

global class LeadProcessor implements 
    Database.Batchable<Leads>, Database.Stateful {
//     Database.Batchable<Sobject>, Database.Stateful {

    
    // instance member to retain state across transactions
    global Integer recordsProcessed = 0;

    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator([Select LastName From Leads ]);

     }
          
    }

    global void execute(Database.BatchableContext bc, List<Leads> scope){
        // process each batch of records
        List<Leads> leads = new List<Leads>();
            for (Leads:leads) {
                Leads.LeadSource = Dreamforce;
                // add Leads to the list to be updated
                leads.add(leads);
                // increment the instance member counter
                recordsProcessed = recordsProcessed + 1;
            }
        }
        update leads;
    }    

    global void finish(Database.BatchableContext bc){
        System.debug(recordsProcessed + ' records processed. Shazam!');
        AsyncApexJob job = [SELECT Id, Status, NumberOfErrors, 
            JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob
            WHERE Id = :bc.getJobId()];
        // call some utility to send email
        EmailUtils.sendMessage(a, recordsProcessed);
    }    

}
Best Answer chosen by SAHG-SFDC
Amit Chaudhary 8Amit Chaudhary 8
Please update your Batch job like below
global class LeadProcessor implements    Database.Batchable<Sobject> 
{
    global Database.QueryLocator start(Database.BatchableContext bc) 
    {
        return Database.getQueryLocator([Select LeadSource From Lead ]);
    }

    global void execute(Database.BatchableContext bc, List<Lead> scope)
    {
            for (Lead Leads : scope) 
            {
                Leads.LeadSource = 'Dreamforce';
            }
        update scope;
    }    

    global void finish(Database.BatchableContext bc){   }    
}
Test class should be like below
@isTest 
public class LeadProcessorTest 
{
    static testMethod void testMethod1() 
    {
        List<Lead> lstLead = new List<Lead>();
        for(Integer i=0 ;i <200;i++)
        {
            Lead led = new Lead();
            led.FirstName ='FirstName';
            led.LastName ='LastName'+i;
            led.Company ='demo'+i;
            lstLead.add(led);
        }
        
        insert lstLead;
        
        Test.startTest();

            LeadProcessor obj = new LeadProcessor();
            DataBase.executeBatch(obj); 
            
        Test.stopTest();
    }
}
Let us know if this will help you

Thanks
Amit Chaudhary


 

All Answers

Amit Chaudhary 8Amit Chaudhary 8
Please update your Batch job like below
global class LeadProcessor implements    Database.Batchable<Sobject> 
{
    global Database.QueryLocator start(Database.BatchableContext bc) 
    {
        return Database.getQueryLocator([Select LeadSource From Lead ]);
    }

    global void execute(Database.BatchableContext bc, List<Lead> scope)
    {
            for (Lead Leads : scope) 
            {
                Leads.LeadSource = 'Dreamforce';
            }
        update scope;
    }    

    global void finish(Database.BatchableContext bc){   }    
}
Test class should be like below
@isTest 
public class LeadProcessorTest 
{
    static testMethod void testMethod1() 
    {
        List<Lead> lstLead = new List<Lead>();
        for(Integer i=0 ;i <200;i++)
        {
            Lead led = new Lead();
            led.FirstName ='FirstName';
            led.LastName ='LastName'+i;
            led.Company ='demo'+i;
            lstLead.add(led);
        }
        
        insert lstLead;
        
        Test.startTest();

            LeadProcessor obj = new LeadProcessor();
            DataBase.executeBatch(obj); 
            
        Test.stopTest();
    }
}
Let us know if this will help you

Thanks
Amit Chaudhary


 
This was selected as the best answer
SAHG-SFDCSAHG-SFDC
Amit,

Yes, It does help, Thanks a lot

I have updated and it works
SAHG-SFDCSAHG-SFDC
Alright, Done

Thanks!
M ParnellM Parnell
I actually received the following error: unexpected token: 'List' on line 6 of my code.
@isTest
public class LeadProcessorTest 
{
	static testMethod void testMethod1()
    {
        List<Lead> 1stLead = new List<Lead>();
        for(Integer i=0 ;i <200;i++)
        {
            Lead led = new Lead();
            led.FirstName = 'FirstName';
            led.LastName = 'LastName' +i;
            led.Company = 'demo' +i;
            1stLead.add(led);
        }
        
        insert 1stLead;
        
        Test.startTest();
        
        	LeadProcessor obj = new LeadProcessor();
        	Database.executeBatch(obj);
        
        Test.stopTest();
    }
}

 
Amit Chaudhary 8Amit Chaudhary 8
try below code

@isTest
public class LeadProcessorTest
{
    static testMethod void testMethod1()
    {
        List<Lead> lstLead = new List<Lead>();
        for(Integer i=0 ;i <200;i++)
        {
            Lead led = new Lead();
            led.FirstName = 'FirstName';
            led.LastName = 'LastName' +i;
            led.Company = 'demo' +i;
            lstLead.add(led);
        }
        insert lstLead;
        Test.startTest();
            LeadProcessor obj = new LeadProcessor();
            Database.executeBatch(obj);
        Test.stopTest();
    }
}
Knowlegde BaseKnowlegde Base
Hi Amit,

I am getting below error
Error: Compile Error: Method does not exist or incorrect signature: Test.startTest() at line 16 column 9

Could you please help me out

Thanks
Knowlegde BaseKnowlegde Base
Able to solve it

Thanks
M ParnellM Parnell
That worked for me Amit. Thanks for your suggestion!
NithutsNithuts
challenge on trail head .im getting 77% code coverage but im getting this error [System.FinalException: Cannot modify a collection while it is being iterated].pls any one help me 
Sarath NSarath N
Can you show your code? Nithya thang 8
NithutsNithuts
Thanks I got answers ..
RainbowRainbow
Thank you  Amit Chaudhary 8 ,
It was really helpful for me. 
The codes were all good but still it wasnot working for me . Later I realized that in the testing class when creating  a new Lead record, we need to be careful about the fileds that are mandatory for lead records. In my case, I was missing StartDate and EndDate. Here is the code below :

@isTest 
public class LeadProcessorTest 
{
    static testMethod void testMethod1() 
    {
        List<Lead> listLead = new List<Lead>();
        for(Integer i=0 ;i<200;i++)
        {
            Lead led = new Lead();
            led.FirstName ='FirstName';
            led.LastName ='LastName'+i;
            led.Company ='Company'+i;
            led.TTSApp__StartDate__c = date.today();
            led.TTSApp__EndDate__c =date.today() + 2;
            
            listLead.add(led);
        }
        
        insert listLead;
        
        Test.startTest();
        
        LeadProcessor obj = new LeadProcessor();
        DataBase.executeBatch(obj); 
            
        Test.stopTest();
    }
}


 
David Bigand 3David Bigand 3
Hello,

I have 1 class and a class test (my 1st in apex). I had to use Batchable to update all entries in a table.

But I'm not able to test more than 60% of the code, and it refuse to deploy.

here is my codes : 
global class UpdateAllValidOnSuiviFinancier implements Database.Batchable<sObject>{

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

        String query = 'SELECT Id  FROM Suivi_Financier__c WHERE  Valide__c = False';

        if(test.isRunningTest()){
            query += ' LIMIT 5';
        }

        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<sObject> scope) {
          for(Suivi_Financier__c sf : (Suivi_Financier__c[])scope){
             sf.Valide__c=True;
          }
        database.update(scope,false);
    }

    global void finish(Database.BatchableContext BC) {

    }

}

and the test class :
@isTest
public class UpdateAllValidOnSuiviFinancierTest {

    @isTest static void testBatch() {
        Test.StartTest();
    UpdateAllValidOnSuiviFinancier uavosf = new UpdateAllValidOnSuiviFinancier();
        ID batchprocessing  = Database.executeBatch(uavosf);
        Test.stopTest();
        System.assertEquals(1,1);
        
                // Récupération des comptes dans Salesforce
        List<Suivi_Financier__c> listOfSuiviFinancier = [SELECT Id,Valide__c  FROM Suivi_Financier__c WHERE Valide__c = True LIMIT 5];
        
        // Verification des points
        Integer size = listOfSuiviFinancier.size();
        System.debug(size);
    System.assertEquals(5, size);

        //System.assertEquals(listOfSuiviFinancier.containsKey(0), True);
    }
    
}

But this indicate that the test is covering only 60% of the main class. I try to add code, asserts... No way to go hover 60%.

Please help

regards

David
Rajnai gRajnai g
Working, Thank you
Singamsetti Sai TejaSingamsetti Sai Teja

Hi

I am not able to cover 100%test coverage even with the above code .

Reshma Asrani 10Reshma Asrani 10
Hello Folks,
I am trying to do exactly as above for this challenge, no errors , test is successful. However, when I check challenge in my trailhead, it gives me below message & so I am not able to complete this challenge. Can someone please advise?
"The 'LeadProcessor' class did not achieve 100% code coverage via your test methods. Make sure that you chose 'Run All' tests in the Developer Console at least once before attempting to verify this challenge."


LeadProcess Class

public class LeadProcessor implements 
    Database.Batchable<sObject>
{

    public Database.QueryLocator start(Database.BatchableContext bc) 
    {
        return Database.getQueryLocator(
            [SELECT LeadSource FROM Lead ]);
    }
    
    public void execute(Database.BatchableContext bc, List<Account> scope)
    {
        // process each batch of records
        List<Lead> leads = new List<Lead>();
        for (Lead lead : leads)
        {
            lead.LeadSource = 'Dreamforce';
            leads.add(lead);
        }
        update leads;    
     }
       
    public void finish(Database.BatchableContext bc)
    {
       
    }    
}

LeadProcessorTest class

@isTest
private class LeadProcessorTest {

    @testSetup 
    static void setup() {
        List<Lead> leads = new List<Lead>();
        
        // insert 200 leads
        for (Integer i=0;i<200;i++) {
            Lead l = new Lead();
            l.LastName = 'Last' + i;
            l.Company = 'myCompany' + i;
            l.Status = 'Open - Not Contacted';
            leads.add(l);
        }
        insert leads;
    }
    
    static testmethod void test() {        
        Test.startTest();
        LeadProcessor mld = new LeadProcessor();
        Database.executeBatch(mld);
        Test.stopTest();
        // after the testing stops, assert records were updated properly
     //  System.assertEquals(200, [select count() from Lead where LeadSource = 'Dreamforce']);
    }
    
}
Reshma Asrani 10Reshma Asrani 10
Hello,
There was some typos & additional lines in my execute() method. I was able to rectify it & successfully able to complete the challenge -
Here is the updated one. 

 public void execute(Database.BatchableContext bc, List<Lead> leads).  //  -->changed type error from Account to Lead
    {
        // process each batch of records
       // List<Lead> leads = new List<Lead>();   -->commented out
        for (Lead lead : leads)
        {
            lead.LeadSource = 'Dreamforce';
          //  leads.add(lead);   ---> commented out
        }
        update leads;    
shradha mhaskeshradha mhaske
Apex Code

global class LeadProcessor implements database.Batchable<sObject>, Database.Stateful{
    global Database.QueryLocator start(Database.BatchableContext bc){
        return Database.getQueryLocator([Select id, Industry from lead ]);
    }
    global void execute(Database.BatchableContext bc, List<Lead> myScope){

        for (Lead leads : myScope) 
        {
            leads.LeadSource = 'Dreamforce';
        }
        Update myScope;
    }
    global void finish(Database.BatchableContext bc){
        
    }
} ​

Test Code

@isTest
public class LeadProcessorTest {

    static TestMethod void testMethod1()
    {
        List<Lead> lists = new list<Lead>();
        for(Integer i=0;i<200;i++)
        {
           Lead led =new Lead();
            led.FirstName = 'FirstName';
            led.LastName ='LastName'+i;
            led.company = 'GenerateLead'+i;
            lists.add(led);
                   
        }
        insert lists;
        Test.startTest();
        {
            LeadProcessor obj = new LeadProcessor();
            DataBase.executeBatch(obj);
        }
        Test.stopTest();
        {
            
        }
        
    }
}
ani ghoani gho
works perfectly fine 100% coverage
public class LeadProcessor implements Database.Batchable<sObject> { 
   
     public Database.QueryLocator start(Database.BatchableContext bc) {
        // collect the batches of records or objects to be passed to execute
          return Database.getQueryLocator([Select LeadSource From Lead ]);
    }
    public void execute(Database.BatchableContext bc, List<Lead> leads){
         // process each batch of records
            for (Lead Lead : leads) {
                lead.LeadSource = 'Dreamforce';
            }
        update leads;
    }    
    public void finish(Database.BatchableContext bc){
      }

}

@isTest
public class LeadProcessorTest {
    
        @testSetup
    static void setup() {
        List<Lead> leads = new List<Lead>();
        for(Integer counter=0 ;counter <200;counter++){
            Lead lead = new Lead();
            lead.FirstName ='FirstName';
            lead.LastName ='LastName'+counter;
            lead.Company ='demo'+counter;
            leads.add(lead);
        }        
        insert leads;
    }
    
    @isTest static void test() {
        Test.startTest();
        LeadProcessor leadProcessor = new LeadProcessor();
        Id batchId = Database.executeBatch(leadProcessor);
        Test.stopTest();   
    }

}

 
Parikshit Sarkar 14Parikshit Sarkar 14
Very interestingly I got the following error while doing this trailhead challenge : 
"No more than one executeBatch can be called from within a test method" 

This occured because I did not set a limit to my query and was trying to fetch more than 200 records from Leads - this will throw the above error while running your test class because a batch can process no more than 200 records per transaction. To avoid this exception please use the below code in your LeadProcessor class: 
 
global class LeadProcessor implements Database.Batchable<sObject> {    
    
    global static Database.QueryLocator start(Database.BatchableContext bc){
		String query = 'Select Id, LeadSource From Lead '+ (test.isRunningTest() ? 'Limit 200' : ''); 
        return Database.getQueryLocator(query);    
    }
    global static void execute(Database.BatchableContext bc, List<Lead> scope){ 
        for(Lead l : scope){
            l.LeadSource = 'Dreamforce'; 
        }
        update scope; 
    }
    global static void finish(Database.BatchableContext bc){ }
}

Hope this helps!

Regards, 
Parikshit Sarkar