0

I am attempting to test a scheduled class that calls a batch class to update records. The following test class does not seem to find the Opportunity being created in the test class to pass that list of records to the batch class. So I am not getting enough coverage as the beginning portion of my batch class is covered but then the execute method does not run as my debug statement shows 0 opps in the list being passed over. Any help you can provide would be absolutely appreciated!

Here is the Scheduled Class:

global class closeOppsEqualOrOver240Days Implements Schedulable
{
    global void execute(SchedulableContext sc)
    {
        CloseAgedOpportunities();
    }
    static public void CloseAgedOpportunities()
    {
        List<Opportunity> lstOpp = new List<Opportunity>();
        
        for(Opportunity opp : [SELECT ID, CloseDate, Opportunity_Age__c, StageName, Loss_Notes__c, Loss_Reason__c,isClosed, Type FROM Opportunity 
                               WHERE (Type = 'New Business' OR Type = 'Existing Business') AND Opportunity_Age__c >= 240 AND
                               (Line_of_Business_Sales_Team__c = 'Channel Sales' OR Line_of_Business_Sales_Team__c = 'Integrated Sales')
                               AND isClosed = False AND From_Internal_Account__c = false]){
            lstOpp.add(opp);
        }
        
        if(lstOpp.size()>0){
            system.debug('This size of the list returned is - '+lstOpp.size());
            database.executeBatch(new closeOppsOlderThan240DaysBatchClass(lstOpp),1);
        }       
}
}

Here is the Batch Class:

global class closeOppsOlderThan240DaysBatchClass implements Database.Batchable<SObject> {

    List<Opportunity> listOfIncomingopps = new List<Opportunity>();
    global closeOppsOlderThan240DaysBatchClass(List<Opportunity> oppList){
        listOfIncomingopps = oppList;
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator([SELECT ID, Opportunity_Age__c,StageName,Loss_Reason__c,Loss_Notes__c from Opportunity
                                        WHERE ID In:listOfIncomingopps]);
    }
    global void execute(Database.BatchableContext BC, List<Opportunity> scope){
        List<Opportunity> oppsToUpdate = new LIst<Opportunity>();
        Id userId;
        Disable_Automation__c setting;
        Boolean disableAutomationAlreadyDisabled = false;    
        userId = userinfo.getUserId();
        setting = Disable_Automation__c.getInstance(userId);
        
        if(setting.All__c == false){
                setting.All__c = true;
                upsert setting;
            }
            else{
                disableAutomationAlreadyDisabled = true;
            }
        for(Opportunity opp : scope){ 
           opp.StageName = 'Closed Lost';
           opp.Loss_Reason__c = 'Other';
           opp.Loss_Notes__c = 'Closed due to maximum allowable age for Opportunity. If the deal is still live, please open a new Opportunity.';
           oppsToUpdate.add(opp);
        }
        
        if(oppsToUpdate.size()>0){
            update oppsToUpdate;
        }
        if(disableAutomationAlreadyDisabled == false){
            setting.All__c = false;
            upsert setting;
        }
    }
    
    global void finish(Database.BatchableContext BC){
        
    }
    
}

And finally here is the test class:

@isTest
public class CloseOppsOlderThan240DaysTest {
    
   public static List<Opportunity> opps = new List<Opportunity>();
    
    static void dataSetup(){
        
        Profile p = [SELECT ID FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
        system.debug('*****_Profile ID found is - '+p.Id);
        
        User u = new User();
        u.LastName = 'Test';
        u.Alias = 't1';
        u.Email = 'example@gmail.com';
        u.UserName = 'setest@gmail.com';
        u.ProfileId = p.Id;
        u.TimeZoneSidKey = 'America/Chicago';
        u.LocaleSidKey = 'en_US';
        u.EmailEncodingKey = 'UTF-8';
        u.LanguageLocaleKey = 'en_US';
        insert u;
        system.debug('*****_User Created Is - '+u.Id);
        
        Disable_Automation__c disableSettings = new Disable_Automation__c(SetupOwnerId = u.Id, All__c = false);
        upsert disableSettings;
        
        Account a = new Account();
            a.Name = 'Test Account';
            insert a;
        system.debug('*****_Account ID Created is - '+a.Id);
        
        List<Opportunity> oppy = new List<Opportunity>();
            Opportunity o = new Opportunity(
            Name = 'Test Opp Update',
            OwnerId = u.Id,
            StageName = 'Qualification',
            CloseDate = date.today().addDays(45),
            Amount = 100,
            AccountId = a.Id,
            CreatedDate = date.Today()-250);
            insert o;
        oppy.add(o);
        opps = oppy;
        system.debug('*****_Opportunity Created ID is - '+o.id);
        
        Product2 prod = new Product2();
        prod.Name = 'MDR-MDR';
        prod.Department__c = 'MDR';
        prod.Description = 'Test MDR Product';
        prod.ProductCode = 'MDR-MDR';
        prod.IsActive = true;
        prod.Product_Code_Unique__c = 'MDR-MDR';
        prod.SBQQ__CostEditable__c = true;
        prod.SBQQ__DefaultQuantity__c = 1;
        prod.SBQQ__SubscriptionCategory__c = 'Renewable';
        prod.SBQQ__SubscriptionTerm__c = 12;
        prod.SBQQ__SubscriptionType__c = 'Renewable';
        insert prod;
        system.debug('*****_Product ID Created is - '+prod.Id);
        
        OpportunityLineItem oli = new OpportunityLineItem();
        oli.OpportunityId = o.Id;
        oli.ARR__c = 5000;
        oli.Quantity = 1;
        oli.SBQQ__ParentID__c = o.Id;
        oli.SBQQ__SubscriptionType__c = 'Renewable';
        oli.CustomerListPrice__c = 50;
        oli.TotalPrice = 5000;
        oli.CS_Unit_Cost__c = 50;
        oli.Prorated_CS_Unit_Cost__c = 25;
        oli.Department__c = 'MDR';
        oli.Is_Renewal__c = false;
        oli.Product2Id = prod.Id;
        insert oli;
        system.debug('*****_Opp Line Item Id created is - '+oli.Id);
        
        
    }
    
    public static String CRON_EXP = '0 0 0 15 3 ? 2022';
    
    static testMethod void testCloseOpps() {
        Test.startTest();
        
        String jobId = System.schedule('ScheduledApexClassTest', CRON_EXP, new closeOppsEqualOrOver240Days());
        
        CronTrigger ct = [SELECT ID, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE Id = :jobId];
        
        system.assertEquals(CRON_EXP, ct.CronExpression);
        system.assertEquals(0, ct.TimesTriggered);
        system.assertEquals('2022-03-15 00:00:00', String.valueOf(ct.NextFireTime));

        
        List<Opportunity> oppsToTest = opps;
        system.debug('*****_OppsToTest List contains '+oppsToTest.size() + ' Opps');
        ID BatchProcessdId = Database.executeBatch(new closeOppsOlderThan240DaysBatchClass(OppsToTest));
        Test.stopTest();
    }

}
  • I would check if the created opportunity is satisfying all the conditions or not. Since we cannot see what would be the values of Line of business Sales team, Type and Internal Account we wouldn't be able to help much, but usually that is the case. Tip: You don't need the logic in scheduler, you can write the same query in batch. – manjit5190 Sep 29 at 16:51
  • Mark, Thank you sir! Type may be it! Thanks for the second set of eyes as the other two are formula fields and should not be needed as those are derived from the account created and the owner. Let me give it a shot and I will report back! – Shawn Sep 29 at 17:24
  • It looks like you're not actually calling your dataSetup() method anywhere, so there's no test data. You either have to mark it as @testSetup, or simply call the method from testCloseOpps(). – rael_kid Sep 29 at 17:28
  • Got it! There was validations not showing, so I added pricebook data and pricebookentry data that was missing as well as using a different user that would populate the one formula field. Once that was completed I am testing out 100 % on both classes. Thanks again for the second set of eyes as that allowed me to continue to troubleshoot and find the root cause. Thanks again! – Shawn Sep 29 at 18:38
0

Got it! There was validations not showing, so I added pricebook data and pricebookentry data that was missing as well as using a different user that would populate the one formula field. Once that was completed I am testing out 100 % on both classes. Thanks again for the second set of eyes as that allowed me to continue to troubleshoot and find the root cause. Thanks again!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.