+ Start a Discussion
Krista KellyKrista Kelly 

Help with apex test class July 27th 2020

Hello, 

I have a Apex class that select records where a field > 0. It then loops through these leads and creates a record in a custom object (Metrics__c). Based on the date it creates a record with a 0 value or with a value > 0. The class works great (tested in Dev Console as a batch) but I'm going in cirlces trying to get the test class past 61%. Any help would be appreciated!

Apex Class

global class MetricProcessor implements Database.Batchable <SObject>,Schedulable {
//START METHOD
global Database.QueryLocator start(Database.BatchableContext bc){

    
    String Query= 'select Id, Console_Logins__c, Console_Last_Logins_Date_Field__c, EP_Catalog__c, EP_Catalog_Date_Field__c, EP_Designer__c, EP_Designer_Date_Field__c, EP_Discovery__c,EP_Discovery_Date_Field__c From Lead where Console_Logins__c > 0';

    return Database.getQueryLocator(Query);

        }

//EXECUTE METHOD

global void execute(Database.BatchableContext bc, List<Lead> scope){

    for(Lead l: scope){

        IF (l.Console_Last_Logins_Date_Field__c > (system.today() - 1))
   {
        //insert record
         
    Metrics__c met = new Metrics__c(
    
         Lead__c=l.ID,

        Name='ConsoleLogins',

        Metric_Value__c=l.Console_Logins__c,

        Metric_Date__c= system.today());

       
    insert met;

    }
    Else
       {//insert 0 record
         Metrics__c met = new Metrics__c(
    
         Lead__c=l.ID,

        Name='ConsoleLogins',

        Metric_Value__c= 0,

        Metric_Date__c= system.today());
        
         insert met;
    }
            IF (l.EP_Catalog_Date_Field__c > (system.today() - 1))
   {
        //insert record
         
    Metrics__c met = new Metrics__c(
    
         Lead__c=l.ID,

        Name='EPCatalog',

        Metric_Value__c=l.EP_Catalog__c,

        Metric_Date__c= system.today());

       
    insert met;

    }
    Else
       {//insert 0 record
         Metrics__c met = new Metrics__c(
    
         Lead__c=l.ID,

        Name='EPCatalog',

        Metric_Value__c= 0,

        Metric_Date__c= system.today());
        
         insert met;
    }
            IF (l.EP_Designer_Date_Field__c > (system.today() - 1))
   {
        //insert record
         
    Metrics__c met = new Metrics__c(
    
         Lead__c=l.ID,

        Name='EPDesigner',

        Metric_Value__c=l.EP_Designer__c,

        Metric_Date__c= system.today());

       
    insert met;

    }
    Else
       {//insert 0 record
         Metrics__c met = new Metrics__c(
    
         Lead__c=l.ID,

        Name='EPDesigner',

        Metric_Value__c= 0,

        Metric_Date__c= system.today());
        
         insert met;
    }
            IF (l.EP_Discovery_Date_Field__c > (system.today() - 1))
   {
        //insert record
         
    Metrics__c met = new Metrics__c(
    
         Lead__c=l.ID,

        Name='EPDiscovery',

        Metric_Value__c=l.EP_Discovery__c,

        Metric_Date__c= system.today());

       
    insert met;

    }
    Else
       {//insert 0 record
         Metrics__c met = new Metrics__c(
    
         Lead__c=l.ID,

        Name='EPDiscovery',

        Metric_Value__c= 0,

        Metric_Date__c= system.today());
        
         insert met;
    }
    }

    update scope;

}


   

//FINISH METHOD

global void finish(Database.BatchableContext bc){

    Id job= bc.getJobId();

    System.debug(job);

}

 

 global void execute(SchedulableContext SC) {

 MetricProcessor l= new MetricProcessor();

ID batchprocessid = Database.executeBatch(l);

}

}

Test Class

@istest
private class MetricProcessorTest {
    @istest

    static void tetslead(){
        List<Lead> l= new List<Lead>();
        lead l1= new Lead();
        l1.LastName='Chaytor';
        l1.Company='Solace';
        l1.Status='Working';
        l1.Console_Logins_Last_Modified__c = system.now();
        l1.Console_Logins__c = 2;
        l1.EP_Catalog_Last_Modified__c = system.now()-2;
        l1.EP_Catalog__c = 0;
        l1.EP_Designer_Last_Modified__c = system.now()-2;
        l1.EP_Designer__c = 0;
        l1.EP_Discovery_Last_Modified__c = system.now();
        l1.EP_Discovery__c = 1;
        l1.LeadSource='Dreamforce';
        l.add(l1);
        insert l;
        
      List<Metrics__c> m= new List<Metrics__c>();
        Metrics__c m1= new Metrics__c();
        m1.Lead__c = l1.Id;
        m1.Name = 'ConsoleLogins';
        m1.Metric_Value__c = 2;
       // m1.Metric_Date__c = system.today();
        
        m.add(m1);
        insert m;
        
        List<Metrics__c> m2= new List<Metrics__c>();
        Metrics__c m3= new Metrics__c();
        m3.Lead__c = l1.Id;
        m3.Name = 'EPCatalog';
        m3.Metric_Value__c = 0;
        //m3.Metric_Date__c = system.today()-;
        
        m2.add(m3);
        insert m2;
        
        List<Metrics__c> m4= new List<Metrics__c>();
        Metrics__c m5= new Metrics__c();
        m5.Lead__c = l1.Id;
        m5.Name = 'EPDesigner';
        m5.Metric_Value__c = 0;
        //m3.Metric_Date__c = system.today()-;
        
        m4.add(m5);
        insert m4;
        
        List<Metrics__c> m7= new List<Metrics__c>();
        Metrics__c m8= new Metrics__c();
        m8.Lead__c = l1.Id;
        m8.Name = 'EPDiscovery';
        m8.Metric_Value__c = 1;
        //m3.Metric_Date__c = system.today()-;
        
        m7.add(m8);
        insert m7;

        
        
    Test.startTest();
    MetricProcessor lp= new MetricProcessor();
    Id jobid= Database.executeBatch(lp);
        String sch = '0 0 * * * ?';
 
system.schedule('ReassignAccountOwner', sch, lp);

       
     
    
 
    Test.stopTest();

    }

}
Best Answer chosen by Krista Kelly
Andrew GAndrew G
The issue, as is often the case, is building the test data to ensure we get into every branch of the IF ... ELSE ... structure.

First, a tweak to your code, you have a loop where you are inserting the records inside the loop one by one.  This is not good for bulkification, so lets build a list to hold the new records and do the insert outside the loop.
 
global class MetricProcessor implements Database.Batchable <SObject>,Schedulable {
//START METHOD
    global Database.QueryLocator start(Database.BatchableContext bc){
        String Query= 'select Id, Console_Logins__c, Console_Last_Logins_Date_Field__c, EP_Catalog__c, EP_Catalog_Date_Field__c, EP_Designer__c, EP_Designer_Date_Field__c, EP_Discovery__c,EP_Discovery_Date_Field__c From Lead where Console_Logins__c > 0';
        return Database.getQueryLocator(Query);
    }

//EXECUTE METHOD

    global void execute(Database.BatchableContext bc, List<Lead> scope){
        //create a list so we do one insert for all the Metrics records
        List<Metrics__c> newMetrics = new List<Metrics__c>;
        for(Lead l: scope){
            if (l.Console_Last_Logins_Date_Field__c > (System.today() - 1))
            {
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='ConsoleLogins',
                        Metric_Value__c=l.Console_Logins__c,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            else
            {//insert 0 record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='ConsoleLogins',
                        Metric_Value__c= 0,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            if (l.EP_Catalog_Date_Field__c > (System.today() - 1))
            {
                //insert record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPCatalog',
                        Metric_Value__c=l.EP_Catalog__c,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            else
            {//insert 0 record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPCatalog',
                        Metric_Value__c= 0,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            if (l.EP_Designer_Date_Field__c > (System.today() - 1))
            {
                //insert record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPDesigner',
                        Metric_Value__c=l.EP_Designer__c,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            else
            {//insert 0 record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPDesigner',
                        Metric_Value__c= 0,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            if (l.EP_Discovery_Date_Field__c > (System.today() - 1))
            {
                //insert record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPDesigner',     //should this be 'EPDiscovery'
                        Metric_Value__c=l.EP_Discovery__c,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            else
            {//insert 0 record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPDiscovery',
                        Metric_Value__c= 0,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
        }
        insert newMetrics;
        update scope;
    }

//FINISH METHOD

    global void finish(Database.BatchableContext bc){
        Id job= bc.getJobId();
        System.debug(job);
    }

    global void execute(SchedulableContext SC) {
        MetricProcessor l= new MetricProcessor();
        Id batchprocessid = Database.executeBatch(l);
    }

}

Now when we do our test class lets build more than one test so that we can hit all the branches and do some asserts that have some meaning.
 
@IsTest
private class MetricProcessorTest {
    @IsTest
    static void testInsertMetrics(){
        List<Lead> l= new List<Lead>();
        Lead l1= new Lead();
        l1.LastName='Chaytor';
        l1.Company='Solace';
        l1.Status='Working';
        l1.Console_Logins_Last_Modified__c = System.now();
        l1.Console_Logins__c = 1;
        l1.EP_Catalog_Last_Modified__c = System.now();
        l1.EP_Catalog__c = 2;
        l1.EP_Designer_Last_Modified__c = System.now();
        l1.EP_Designer__c = 3;
        l1.EP_Discovery_Last_Modified__c = System.now();
        l1.EP_Discovery__c = 4;
        l1.LeadSource='Dreamforce';
        l.add(l1);
        insert l;

        Test.startTest();
        MetricProcessor lp= new MetricProcessor();
        Id jobid= Database.executeBatch(lp);
        String sch = '0 0 * * * ?';

        System.schedule('ReassignAccountOwner', sch, lp);

        Test.stopTest();

        List<Metrics__c> newMetrics = new List<Metrics__c>();

        newMetrics = [SELECT Id, Name, Metric_Value__c, Metric_Date__c FROM Metrics WHERE Lead__c = :li.Id  ORDER BY Metric__value__c];

        System.assertEquals(4,newMetrics.size());

        System.assertEquals(1,newMetrics[0].Metric_Value__c);
        System.assertEquals('ConsoleLogins',newMetrics[0].Name);
        System.assertEquals(2,newMetrics[1].Metric_Value__c);
        System.assertEquals('EPCatalog',newMetrics[1].Name);
        System.assertEquals(3,newMetrics[2].Metric_Value__c);
        System.assertEquals('EPDesigner',newMetrics[2].Name);
        System.assertEquals(4,newMetrics[3].Metric_Value__c);
        System.assertEquals('EPDesigner',newMetrics[3].Name);

    }

    @IsTest
    static void testInsertZeroMetrics(){
        List<Lead> l= new List<Lead>();
        Lead l1= new Lead();
        l1.LastName='Chaytor';
        l1.Company='Solace';
        l1.Status='Working';
        l1.Console_Logins_Last_Modified__c = System.now()-2;
        l1.Console_Logins__c = 1;
        l1.EP_Catalog_Last_Modified__c = System.now()-2;
        l1.EP_Catalog__c = 2;
        l1.EP_Designer_Last_Modified__c = System.now()-2;
        l1.EP_Designer__c = 3;
        l1.EP_Discovery_Last_Modified__c = System.now()-2;
        l1.EP_Discovery__c = 4;
        l1.LeadSource='Dreamforce';
        l.add(l1);
        insert l;

        Test.startTest();
        MetricProcessor lp= new MetricProcessor();
        Id jobid= Database.executeBatch(lp);
        String sch = '0 0 * * * ?';

        System.schedule('ReassignAccountOwner', sch, lp);

        Test.stopTest();

        List<Metrics__c> newMetrics = new List<Metrics__c>();

        newMetrics = [SELECT Id, Name, Metric_Value__c, Metric_Date__c FROM Metrics WHERE Lead__c = :li.Id  ORDER BY Name];

        System.assertEquals(4,newMetrics.size());

        System.assertEquals(0,newMetrics[0].Metric_Value__c);
        System.assertEquals('ConsoleLogins',newMetrics[0].Name);
        System.assertEquals(0,newMetrics[1].Metric_Value__c);
        System.assertEquals('EPCatalog',newMetrics[1].Name);
        System.assertEquals(0,newMetrics[2].Metric_Value__c);
        System.assertEquals('EPDesigner',newMetrics[2].Name);
        System.assertEquals(0,newMetrics[3].Metric_Value__c);
        System.assertEquals('EPDiscovery',newMetrics[3].Name);

    }

}

Note that in the first test method we have test data that will fulfill all the IF components of the code.   In the second test , we have data that will drive into each of the ELSE components of the code.


Also note, that when posting code, the code snippet button helps make the code more readable:
User-added image

Regards

Andrew

P.S.  all code is provided uncompiled and As-Is.
 

All Answers

Andrew GAndrew G
The issue, as is often the case, is building the test data to ensure we get into every branch of the IF ... ELSE ... structure.

First, a tweak to your code, you have a loop where you are inserting the records inside the loop one by one.  This is not good for bulkification, so lets build a list to hold the new records and do the insert outside the loop.
 
global class MetricProcessor implements Database.Batchable <SObject>,Schedulable {
//START METHOD
    global Database.QueryLocator start(Database.BatchableContext bc){
        String Query= 'select Id, Console_Logins__c, Console_Last_Logins_Date_Field__c, EP_Catalog__c, EP_Catalog_Date_Field__c, EP_Designer__c, EP_Designer_Date_Field__c, EP_Discovery__c,EP_Discovery_Date_Field__c From Lead where Console_Logins__c > 0';
        return Database.getQueryLocator(Query);
    }

//EXECUTE METHOD

    global void execute(Database.BatchableContext bc, List<Lead> scope){
        //create a list so we do one insert for all the Metrics records
        List<Metrics__c> newMetrics = new List<Metrics__c>;
        for(Lead l: scope){
            if (l.Console_Last_Logins_Date_Field__c > (System.today() - 1))
            {
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='ConsoleLogins',
                        Metric_Value__c=l.Console_Logins__c,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            else
            {//insert 0 record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='ConsoleLogins',
                        Metric_Value__c= 0,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            if (l.EP_Catalog_Date_Field__c > (System.today() - 1))
            {
                //insert record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPCatalog',
                        Metric_Value__c=l.EP_Catalog__c,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            else
            {//insert 0 record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPCatalog',
                        Metric_Value__c= 0,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            if (l.EP_Designer_Date_Field__c > (System.today() - 1))
            {
                //insert record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPDesigner',
                        Metric_Value__c=l.EP_Designer__c,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            else
            {//insert 0 record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPDesigner',
                        Metric_Value__c= 0,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            if (l.EP_Discovery_Date_Field__c > (System.today() - 1))
            {
                //insert record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPDesigner',     //should this be 'EPDiscovery'
                        Metric_Value__c=l.EP_Discovery__c,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
            else
            {//insert 0 record
                Metrics__c met = new Metrics__c(
                        Lead__c=l.Id,
                        Name='EPDiscovery',
                        Metric_Value__c= 0,
                        Metric_Date__c= System.today());
                newMetrics.add(met) ;
            }
        }
        insert newMetrics;
        update scope;
    }

//FINISH METHOD

    global void finish(Database.BatchableContext bc){
        Id job= bc.getJobId();
        System.debug(job);
    }

    global void execute(SchedulableContext SC) {
        MetricProcessor l= new MetricProcessor();
        Id batchprocessid = Database.executeBatch(l);
    }

}

Now when we do our test class lets build more than one test so that we can hit all the branches and do some asserts that have some meaning.
 
@IsTest
private class MetricProcessorTest {
    @IsTest
    static void testInsertMetrics(){
        List<Lead> l= new List<Lead>();
        Lead l1= new Lead();
        l1.LastName='Chaytor';
        l1.Company='Solace';
        l1.Status='Working';
        l1.Console_Logins_Last_Modified__c = System.now();
        l1.Console_Logins__c = 1;
        l1.EP_Catalog_Last_Modified__c = System.now();
        l1.EP_Catalog__c = 2;
        l1.EP_Designer_Last_Modified__c = System.now();
        l1.EP_Designer__c = 3;
        l1.EP_Discovery_Last_Modified__c = System.now();
        l1.EP_Discovery__c = 4;
        l1.LeadSource='Dreamforce';
        l.add(l1);
        insert l;

        Test.startTest();
        MetricProcessor lp= new MetricProcessor();
        Id jobid= Database.executeBatch(lp);
        String sch = '0 0 * * * ?';

        System.schedule('ReassignAccountOwner', sch, lp);

        Test.stopTest();

        List<Metrics__c> newMetrics = new List<Metrics__c>();

        newMetrics = [SELECT Id, Name, Metric_Value__c, Metric_Date__c FROM Metrics WHERE Lead__c = :li.Id  ORDER BY Metric__value__c];

        System.assertEquals(4,newMetrics.size());

        System.assertEquals(1,newMetrics[0].Metric_Value__c);
        System.assertEquals('ConsoleLogins',newMetrics[0].Name);
        System.assertEquals(2,newMetrics[1].Metric_Value__c);
        System.assertEquals('EPCatalog',newMetrics[1].Name);
        System.assertEquals(3,newMetrics[2].Metric_Value__c);
        System.assertEquals('EPDesigner',newMetrics[2].Name);
        System.assertEquals(4,newMetrics[3].Metric_Value__c);
        System.assertEquals('EPDesigner',newMetrics[3].Name);

    }

    @IsTest
    static void testInsertZeroMetrics(){
        List<Lead> l= new List<Lead>();
        Lead l1= new Lead();
        l1.LastName='Chaytor';
        l1.Company='Solace';
        l1.Status='Working';
        l1.Console_Logins_Last_Modified__c = System.now()-2;
        l1.Console_Logins__c = 1;
        l1.EP_Catalog_Last_Modified__c = System.now()-2;
        l1.EP_Catalog__c = 2;
        l1.EP_Designer_Last_Modified__c = System.now()-2;
        l1.EP_Designer__c = 3;
        l1.EP_Discovery_Last_Modified__c = System.now()-2;
        l1.EP_Discovery__c = 4;
        l1.LeadSource='Dreamforce';
        l.add(l1);
        insert l;

        Test.startTest();
        MetricProcessor lp= new MetricProcessor();
        Id jobid= Database.executeBatch(lp);
        String sch = '0 0 * * * ?';

        System.schedule('ReassignAccountOwner', sch, lp);

        Test.stopTest();

        List<Metrics__c> newMetrics = new List<Metrics__c>();

        newMetrics = [SELECT Id, Name, Metric_Value__c, Metric_Date__c FROM Metrics WHERE Lead__c = :li.Id  ORDER BY Name];

        System.assertEquals(4,newMetrics.size());

        System.assertEquals(0,newMetrics[0].Metric_Value__c);
        System.assertEquals('ConsoleLogins',newMetrics[0].Name);
        System.assertEquals(0,newMetrics[1].Metric_Value__c);
        System.assertEquals('EPCatalog',newMetrics[1].Name);
        System.assertEquals(0,newMetrics[2].Metric_Value__c);
        System.assertEquals('EPDesigner',newMetrics[2].Name);
        System.assertEquals(0,newMetrics[3].Metric_Value__c);
        System.assertEquals('EPDiscovery',newMetrics[3].Name);

    }

}

Note that in the first test method we have test data that will fulfill all the IF components of the code.   In the second test , we have data that will drive into each of the ELSE components of the code.


Also note, that when posting code, the code snippet button helps make the code more readable:
User-added image

Regards

Andrew

P.S.  all code is provided uncompiled and As-Is.
 
This was selected as the best answer
Krista KellyKrista Kelly
Andrew, thank you SO much! It’s now at 100% code coverage. I’m new to Apex and was struggling so I really appreciate you helping me!
mark jones 123mark jones 123
Thank you so much for such a well-written article. It’s full of insightful information. Your point of view is the best among many without fail. For certain, it is one of the best blogs in my opinion. Today I found great website (Freelicensekeys.com) where you get all 100% working free license keys, like -Filmora crack (https://www.freelicensekeys.com/2020/07/wondershare-filmora-9-registration-key.html" name="_Hlk46853505), Window 7 products keys and many more.
jey welljey well
Best collection of Sad Shayari (https://statussove.com/sad-shayari/) in Hindi and English