function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Tom Barad 11Tom Barad 11 

Test Class for Trigger using System.Now() in a Calculation

Hi,

I'm trying to write a test class for a trigger that uses system.now() in a calculation of "first response age" and "resolved age" on Case.  The test sometimes fails because of minute differences in system datetime between when the record is created and when the test class executes.  For example, the difference between Open Datetime and system.now() calculates to "0.0013888888..." when my trigger class calculates and updates my case record, but when the test class recalculates First Response Age for the system.assert, and I select from the database to compare, the First Response Age calculates to "0.001688888...", so the system.assert fails.  I've even tried rounding the results, but to no avail... Is there a way to use system.now() in a test class so calculations against it reliably produce the same results between the test class and the trigger?  Is there a different way to do this?  Thanks in advance!

Trigger:
trigger CalculateResponseResolvedAge on Case (before update, before insert) {
    
    if (Trigger.isInsert) {
        for (Case updatedCase:System.Trigger.new) {
            updatedCase.First_Response_Age__c = 0.000;
            updatedCase.Resolved_Age__c = 0.000;
        }
    }
    
    if (Trigger.isUpdate) {
        //Set the response statuses
        Set<String> responseStatusSet = new Set<String>();
        responseStatusSet.add('In Progress');
        responseStatusSet.add('Closed');
        responseStatusSet.add('Resolved');
        
        //Set the resolved statuses
        Set<String> resolvedStatusSet = new Set<String>();
        resolvedStatusSet.add('Closed');
        resolvedStatusSet.add('Resolved');
        
        //Get the default business hours (we might need it)
        //BusinessHours defaultHours = [select Id from BusinessHours where IsDefault=true];
        
        //For any case where the status is changed, recalc the business hours in the buckets
        for (Case updatedCase:System.Trigger.new) {
            Case oldCase = System.Trigger.oldMap.get(updatedCase.Id);
            if (oldCase.Status!=updatedCase.Status) {
                //OK, the status has changed
                Id hoursToUse = updatedCase.BusinessHoursId;
                //The diff method comes back in milliseconds, so we divide by 1000.
                Long timeDifference = BusinessHours.diff(hoursToUse, updatedCase.CreatedDate, System.now())/1000;
                Decimal timeSinceOpened = 0.000;
                timeSinceOpened.setScale(3);
                timeSinceOpened = timeDifference/60.000/60.000;
                timeSinceOpened.round(System.RoundingMode.DOWN);
                //We decide which age to set based on the status and if the age is null
                if (updatedCase.Status=='New') {
                    updatedCase.First_Response_Age__c = 0.000;
                    updatedCase.Resolved_Age__c = 0.000;
                }           
                if (responseStatusSet.contains(updatedCase.Status) && updatedCase.First_Response_Age__c==0.000 ) {
                    updatedCase.First_Response_Age__c = timeSinceOpened;
                } 
                if (resolvedStatusSet.contains(updatedCase.Status) && updatedCase.Resolved_Age__c==0.000) {
                    updatedCase.Resolved_Age__c = timeSinceOpened;
                }
            }
        }
    }
}
Test Class:
@isTest
private class CalculateResponseResolvedAgeTest {
    static testMethod void validateResponseResolvedAge () {
        
        // before Insert
        Case c = new Case(Category__c='Network and Systems');
        insert c;
        c = [SELECT First_Response_Age__c, Resolved_Age__c, CreatedDate, BusinessHoursId
             FROM Case WHERE Id =:c.Id];
        System.assertEquals(0.000, c.First_Response_Age__c);
        System.assertEquals(0.000, c.Resolved_Age__c);
        
        // before Update - In Progress
        c.Status = 'In Progress';
        System.debug('First Response Case Status: ' + c.Status);
        Long timeDifferenceInProgress = BusinessHours.diff(c.BusinessHoursId, c.CreatedDate, System.now())/1000;
        Decimal timeSinceOpenedInProgress = 0.000;
        timeSinceOpenedInProgress = timeDifferenceInProgress/60.000/60.000;
        timeSinceOpenedInProgress.round(System.RoundingMode.DOWN);
        upsert c;
        c = [SELECT First_Response_Age__c, Resolved_Age__c, CreatedDate, BusinessHoursId
             FROM Case WHERE Id =:c.Id];
        System.assertEquals(timeSinceOpenedInProgress, c.First_Response_Age__c);
        System.assertEquals(0.000, c.Resolved_Age__c);
        
        // before Update - Resolved
        c.Status = 'Resolved';
        System.debug('Resolved Case Status: ' + c.Status);
        Long timeDifferenceResolved = BusinessHours.diff(c.BusinessHoursId, c.CreatedDate, System.now())/1000;
        Decimal timeSinceOpenedResolved = 0.000;
        timeSinceOpenedResolved = timeDifferenceResolved/60.000/60.000;
        timeSinceOpenedResolved.round(System.RoundingMode.DOWN);
        upsert c;
        c = [SELECT First_Response_Age__c, Resolved_Age__c, CreatedDate, BusinessHoursId
             FROM Case WHERE Id =:c.Id];
        System.assertEquals(timeSinceOpenedResolved, c.Resolved_Age__c);
        
        // before Update - New
        c.Status = 'New';
        System.debug('New Case Status: ' + c.Status);
        upsert c;
        c = [SELECT First_Response_Age__c, Resolved_Age__c, CreatedDate, BusinessHoursId
             FROM Case WHERE Id =:c.Id];
        System.assertEquals(0.000, c.Resolved_Age__c);
        System.assertEquals(0.000, c.First_Response_Age__c);

        // before Update - Resolved 2
        c.Status = 'Resolved';
        System.debug('Resolved Case Status: ' + c.Status);
        Long timeDifferenceResolved2 = BusinessHours.diff(c.BusinessHoursId, c.CreatedDate, System.now())/1000;
        Decimal timeSinceOpenedResolved2 = 0.000;
        timeSinceOpenedResolved2 = timeDifferenceResolved2/60.000/60.000;
        timeSinceOpenedResolved2.round(System.RoundingMode.DOWN);
        upsert c;
        c = [SELECT First_Response_Age__c, Resolved_Age__c, CreatedDate, BusinessHoursId
             FROM Case WHERE Id =:c.Id];
        System.assertEquals(timeSinceOpenedResolved2, c.Resolved_Age__c);
        System.assertEquals(timeSinceOpenedResolved2, c.First_Response_Age__c);


    }
}