Question:

Test Not Covering All My Trigger Code

Wyatt: 5 days ago

I have created a trigger that fires when a Task is Inserted, Updated, or Deleted. When it fires, it updates custom checkboxes on open Opportunities based upon the Subject of the Task and checks to see that the ActivityDate is within the effective and renewal dates of the Opp. All works fine, however, I am not able to get my test to cover the part of the code that works on checking one of the boxes after an update. Can anyone advise on how I can get the code covered below (Specifically line 14 and lines 19-37 of the Trigger Class?

Trigger

IF(Trigger.IsUpdate){
    ClassRenewalTaskCount updater4 = new ClassRenewalTaskCount();
    updater4.taskCountUpdate(Trigger.new,Trigger.old);

}

Trigger Class

public class ClassRenewalTaskCount {

Set<ID> OppIds = new Set<ID>();
Set<ID> TaskIdsRem = new Set<ID>();

    String acctPrefix = Account.SObjectType.getDescribe().getKeyPrefix();

public void taskCountUpdate(List<Task> checkTasks, List<Task> oldTasks) {

    for (Task t : checkTasks) {
        for (Task prev : oldTasks){
            //Adds a task that is updated to completed and current
            if (t.WhatId != null && t.Status == 'Completed' && t.RP_Prior_60__c <= t.ActivityDate && string.valueof(t.WhatId).startsWith(acctPrefix) ) {
                OppIds.add(t.WhatId);              
            }
        }
    }

    if (OppIds.size() > 0){

        List<Account> acctsWithTasks = [SELECT Id,(SELECT Id FROM Tasks)
                                        FROM Account
                                        WHERE Id IN : OppIds];

            List<Opportunity> oppsUpdatable = new List<Opportunity>();

                for(Account acct : acctsWithTasks){
                    for(Opportunity L : [SELECT Id,Account.Id,RP_Customer_Engagement__c,IsWon
                                        FROM Opportunity
                                        WHERE Account.Id =: acct.Id AND IsWon=FALSE]){
                    L.RP_Customer_Engagement__c = acct.Tasks.size();
                    oppsUpdatable.add(L);
                    }
                }

        if(oppsUpdatable.size()>0){
            update oppsUpdatable;
        }
    }
    }
}

Test Method

static testmethod void testRenewalTasks3(){

    Account acct1 = TestCreateRecords.createAcct(0);
    insert acct1;

    Opportunity opp1 = TestCreateRecords.createOppNew(acct1.Id);
    insert opp1;
        opp1.RP_Customer_Engagement__c = 0;
        UPDATE opp1;

    Task task1 = TestCreateRecords.createTaskInitProg(acct1.Id);
    INSERT task1;

    Task task2 = new task();
    task2.WhatId = acct1.Id;
    task2.ActivityDate = date.parse('1/5/15');
    task2.Subject = 'Offerpop User Training Complete';
    task2.Status = 'In Progress';
    task2.Priority = 'Normal';
    INSERT task2;


Test.startTest();
    Task tsk1 = [SELECT Id,ActivityDate,Status
                FROM Task
                WHERE Id =: task1.Id];
    tsk1.Status = 'In Progress';
    UPDATE tsk1;

    Task tsk2 = [SELECT Id,ActivityDate,Status
                FROM Task
                WHERE Id =: tsk1.Id];
    tsk2.Status = 'Completed';
    UPDATE tsk2;
Test.stopTest();
}

Answer:
Everly: 5 days ago

Your filter needs to return results:

if (t.WhatId != null && t.Status == 'Completed' && t.RP_Prior_60__c <= t.ActivityDate && string.valueof(t.WhatId).startsWith(acctPrefix) )

In your test, you never set Task.RP_Prior_60__c. Hence no task meets the entire set of criteria.

It may be easier to test this if you separate your two concerns, getting the relevant Id set and then acting on those Ids.

static Set<Id> getAccountIds(List<Task> newTasks, List<Task> oldTasks)
{
    // perform filtering
    // do you really need the old records?
}

static void updateTaskCount(Set<Id> accountIds)
{
    // perform action
}