3

I have a task trigger which updates two custom fields on the Account object : Last_Call_Date and Last_Meeting_Date. I have tried logging a task in sandbox and it updates the fields correctly. However, my unit test always fails, saying that the date in the db is null instead of the current date. Any idea why?

Here is my trigger:

trigger SetLastActivityDate_Task on Task (after insert, after update, after delete, after undelete) {
    Map<Id, Account> accounts = new Map<Id, Account>();
    for (Task t : (Trigger.isDelete ? Trigger.old : Trigger.new)) {
        accounts.put(t.AccountId, new Account(
            Id = t.AccountId,
            Last_Call_Date__c = null,
            Last_Meeting_Date__c = null
        ));
        if (Trigger.isUpdate) {
            Id aIdOld = Trigger.oldMap.get(t.Id).AccountId;
            accounts.put(aIdOld, new Account(
                Id = aIdOld,
                Last_Call_Date__c = null,
                Last_Meeting_Date__c = null
            ));
        }
    }
    accounts.remove(null);

    Date activityDate = Date.today();

    if (!accounts.isEmpty()) {

        // Last Meeting Date
        for (Account a : [SELECT Id, (SELECT ActivityDate FROM ActivityHistories WHERE ActivityDate<>NULL AND ActivityDate<=:activityDate AND ActivityType='Meeting' ORDER BY ActivityDate DESC LIMIT 1) FROM Account WHERE Id IN :accounts.keySet()]) {
            for (ActivityHistory t : a.ActivityHistories) {
                accounts.get(a.Id).Last_Meeting_Date__c = t.ActivityDate;
            }
        }
        // Last Call Date
        for (Account a : [SELECT Id, (SELECT ActivityDate FROM ActivityHistories WHERE ActivityDate<>NULL AND ActivityDate<=:activityDate AND ActivityType='Call' ORDER BY ActivityDate DESC LIMIT 1) FROM Account WHERE Id IN :accounts.keySet()]) {
            for (ActivityHistory t : a.ActivityHistories) {
                accounts.get(a.Id).Last_Call_Date__c = t.ActivityDate;
            }
        }       
        update accounts.values();
    }
}

And my test:

@isTest
public class TestTaskTrigger {
    public static testMethod void testSetDates(){

        Test.startTest();

        Account a = new Account(Name = 'Test Account');
        insert a;
        Contact c = new Contact(FirstName = 'Testing', LastName = 'Dates', AccountId = a.Id);
        insert c;

        Task tCall = new Task(WhoId = c.Id, Subject = 'TestCall', WhatId = a.Id, Type = 'Call', ActivityDate = Date.today(), Status = 'Completed');
        Task tMeeting = new Task(WhoId = c.Id, Subject = 'TestMeeting', WhatId = a.Id, Type = 'Meeting', ActivityDate = Date.today(), Status = 'Completed');

        insert tMeeting;    
        // Verification
        Account a1 = [select Id, Name, Last_Call_Date__c, Last_Meeting_Date__c from Account where Id = :a.Id];
        System.assertEquals('Test Account', a1.Name);
        System.assertEquals(Date.today(), a1.Last_Meeting_Date__c);
        System.assertEquals(null, a1.Last_Call_Date__c);

        insert tCall;
        a1 = [select Id, Last_Meeting_Date__c, Last_Call_Date__c from Account where Id = :a.Id];
        System.assertEquals(Date.today(), a1.Last_Call_Date__c);

        Test.stopTest();        
    }
}

Here is what I get: System.AssertException: Assertion Failed: Expected: 2017-01-24 00:00:00, Actual: null

This refers to the line:

System.assertEquals(Date.today(), a1.Last_Meeting_Date__c);

Since the inserted task is of type meeting, I would expect this date to be updated. And it does get updated to today's date if I try to log a meeting.

4
  • 3
    Can you specify what assert is failing. That will give people a good starting point. Jan 24, 2017 at 20:53
  • I just added that to the bottom of the post.
    – nadajp
    Jan 24, 2017 at 21:33
  • Why are you querying ActivityHistory instead of Task?
    – Avinash
    Jan 24, 2017 at 21:53
  • Are the tasks not a part of ActivityHistory? Why do you think this is problematic?
    – nadajp
    Jan 25, 2017 at 17:05

2 Answers 2

0

Try below code it will surly help you.

@isTest(seeAllData=true)
public class TestTask {
    public static testMethod void testSetDates(){

        Test.startTest();
        date dt=Date.today();
        Account a = new Account(Name = 'Test Account');
        insert a;
        Contact c = new Contact(FirstName = 'Testing', LastName = 'Dates', AccountId = a.Id);
        insert c;

        Task tCall = new Task(WhoId = c.Id, Subject = 'TestCall', WhatId = a.Id, Type = 'Call', ActivityDate = Date.today(), Status = 'Completed');
        Task tMeeting = new Task(WhoId = c.Id, Subject = 'TestMeeting', WhatId = a.Id, Type = 'Meeting', ActivityDate = Date.today(), Status = 'Completed');

        insert tMeeting;    
        // Verification
        Account a1 = [select Id, Name, Last_Call_Date__c, Last_Meeting_Date__c from Account where Id = :a.Id];
        System.assertEquals('Test Account', a1.Name);
        System.assertEquals(Date.today(), a1.Last_Meeting_Date__c);
        System.assertEquals(null, a1.Last_Call_Date__c);

        insert tCall;
        a1 = [select Id, Last_Meeting_Date__c, Last_Call_Date__c from Account where Id = :a.Id];
        System.assertEquals(Date.today(), a1.Last_Call_Date__c);

        Test.stopTest();        
    }
}

Note:- For some reason, we need to use @isTest(seeAllData=true) in order to see ActivityHistory in unit tests.

0

If you want to use ActivityHistories in your test method then you will have to restructure your code a bit to accommodate.

You have 3 ways to go:

  1. Instead of executing the query directly in your class, use a helper method so to speak. Have it return ActivityHistories based on if test is running or not

     public ActivityHistory[] testActivityHistories;
    
     public ActivityHitory[] getAppropriateHistory(Account a){
         test.isRunningTest() ? testActivityHistories : a.ActivityHistories;
     }
    

Then in your test set the testHistories before inserting you record by creating it:

testActivityHistories = New ActivityHistory(...populate values here..)

Then in your code use this in the trigger

for (ActivityHistory t : getAppropriateHistory(a))

Now I admit that this will not test the fact that a history is written or not but that is a system function that we can be assured will happen. If it does not then we have bigger problems anyway. This will however allow you to test your logic

  1. Query Tasks instead. ActivityHistory is a collection of tasks and events that have been marked completed. You could a similar thing by querying the associated tasks with the appropriate criteria instead. Not that what you are doing is wrong it just makes it more difficult to test

  2. Use SELLALLDATA=TRUE - Unit Tests: create completed tasks for ActivityHistory?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .