[SalesForce] CaseHistory is not created

I am writing an Apex test for a trigger that fires when creating or updating cases.

Per the Salesforce documentation, CaseHistory objects are created automatically when updating Case objects:

Usage

Case history entries are indirectly created each time a case is modified.

In my test, I am performing a total of five updates to a Case to fire the trigger multiple times:

static testMethod void doTest() {
  // <snip> 40 lines of setting up test data for this monster of a trigger

  Test.startTest();
  Case case = new Case();
  case.AccountId = acct.Id;
  case.Description = 'Description';
  case.Priority = 'Medium';
  case.Status = 'New';
  insert case;

  case.Status = 'Assigned';
  update case;

  // <snip> three status updates

  case.Status = 'Closed';
  update case;

  Test.stopTest();

  // Debug code showing no histories created
  List<SObject> caseHistories = [SELECT ... FROM CaseHistory WHERE CaseId = :case.Id];
  System.debug('CASE HISTORIES = ' + caseHistories);

  System.assert(...);
}

Then in the trigger, there is this code. The body of the loop does not execute: it has no code coverage reported. I validated using debug statements that caseIds does have list elements.

for(CaseHistory aCaseHistory : [SELECT ... FROM CaseHistory
    WHERE Field = 'Status' and CaseId IN :caseIds]) {
  // Loop body does not execute.
}

I added the following debug logging to my test class, which is located at the end after all DML statements have run. Note that the SOQL is similar to the test but I omitted the Field field, opting to query all CaseHistory objects for the Cases I am manipulating.

List<SObject> caseHistories = [SELECT ... FROM CaseHistory WHERE CaseId = :case.Id];
System.debug('CASE HISTORIES = ' + caseHistories);

This provides the following in the debug log:

USER_DEBUG|[117]|DEBUG|CASE HISTORIES = ()

After all of this investigation, I have to conclude that CaseHistory objects are not, in fact, being created when updating Cases which contradicts the Salesforce documentation. Since I am firing one insert and five updates, this should not be an issue with the user trigger firing before or after the automatic functionality running (but this particular code does run after update).

What would cause this, and how do I resolve it?

For the record, I did read Incorrect Salesforce documentation and I am open to the idea that perhaps the documentation is incorrect or incomplete: however, I am going on the assumption that it is correct and I do not understand some aspect of the Salesforce platform.

Resolution

Per the accepted answer, history objects are created by Salesforce when committing records. Since tests do not commit data, they will not be created. This means there is no way to test this logic. Related question: How do I write test for a Histories Inner query?

Best Answer

Take a look at the related list on the case detail page, are they being created?

If your trigger is running when on the Case record, then no, you wont have access to the CaseHistory records at that point in time. You'll need to run the logic outside of your Case trigger, perhaps in a batch / scheduled class.

An alternative, is instead of keying off of CaseHistory, you can compare the old Case values with the new Case values in your trigger.

For example if you wanted to compare to see if the case was closed as part of this transaction, you could do the following in a trigger:

if(Trigger.oldMap == null || (Trigger.oldMap.get(currentCase.Id).Status != 'Closed' && currentCase.Status == 'Closed'))

//Edit: According to this post: How do I write test for a Histories Inner query? History records are not created as part of unit tests. Sounds like you might be out of luck. Your only options the way I see it are 1) Ignorning any CaseHistory logic in your assertions and/or 2) Implement special unit test handling for Case Histories using Test.isRunningTest()

Related Topic