You need to sign in to do that
Don't have an account?
Test method for Custom Object History
I have created a custom history related list for a custom object. But I dont know how to write a test method for that. Here is the code:
public list<cHistories> getHistories()
{
// Initialize list to be returned
list<cHistories> list_ch = new list<cHistories>();
// Loop through all field history records
for (Mapping_Object__History fh: [select ParentId,OldValue,NewValue,IsDeleted,Id,Field,CreatedDate,CreatedById,CreatedBy.Name
From Mapping_Object__History
where ParentId =:mapping.id
order by CreatedDate desc])
{
// Create a new wrapper object
cHistories ch = new cHistories();
// Set the Date
ch.theDate = String.valueOf(fh.createddate);
// Set who performed the action
ch.who = fh.createdby.name;
// Set the Action value
if (String.valueOf(fh.Field) == 'created')
{ // on Creation
ch.action = 'Created.';
}
else if (fh.OldValue != null && fh.NewValue == null)
{ // when deleting a value from a field
// Format the Date and if there's an error, catch it and re
try {
ch.action = 'Deleted ' + Date.valueOf(fh.OldValue).format() + ' in <b>' + Schema.getGlobalDescribe().get('Mapping_Object__c').getDescribe().fields.getMap().get(String.valueOf(fh.Field)).getDescribe().getLabel() + '</b>.';
} catch (Exception e){
ch.action = 'Deleted ' + String.valueOf(fh.OldValue) + ' in <b>' + Schema.getGlobalDescribe().get('Mapping_Object__c').getDescribe().fields.getMap().get(String.valueOf(fh.Field)).getDescribe().getLabel() + '</b>.';
}
}
else
{ // all other scenarios
String fromText = '';
if (fh.OldValue != null)
{
try {
fromText = ' from ' + Date.valueOf(fh.OldValue).format();
} catch (Exception e) {
fromText = ' from ' + String.valueOf(fh.OldValue);
}
}
String toText = '';
try {
toText = ' ' + Date.valueOf(fh.NewValue).format();
} catch (Exception e) {
toText = ' ' + String.valueOf(fh.NewValue);
}
ch.action = 'Changed <b>' + Schema.getGlobalDescribe().get('Mapping_Object__c').getDescribe().fields.getMap().get(String.valueOf(fh.Field)).getDescribe().getLabel() + '</b>' + fromText + ' to <b>' + toText + '</b>.';
}
list_ch.add(ch);
}
return list_ch;
}
public class cHistories
{
// Class properties
public String theDate {get; set;}
public String who {get; set;}
public String action {get; set;}
}
When I tried to insert a record into the History object in the test method, It is throwing error that insertion operation is not allowed for History objects. Does anyone know of a solution?
In this section:
rather than processing the list once you have retrieved it, pass the list of Mapping_Object__History records to another method. When testing, you can create instances of Mapping_Object__History records and pass these directly to that method also. Thus the only code that you can't test is the actual query (although the query might succeed, I can't really remember what happened with that).
All Answers
I went through this a few years ago. You can't insert directly into the history table and you can't update in a test context that causes a record to be written to the history table as it requires the transaction to complete, but test transactions don't complete.
I ended up refactoring the code so that the code that processes the history records was decoupled from the query. Then I was able to instantiate query records in my test method and pass them through to the processing code and thus test that was behaving as expected.
Hi Bob,
Thanks for the reply. Can you please elaborate this. Because I am new to Apex programming.
In this section:
rather than processing the list once you have retrieved it, pass the list of Mapping_Object__History records to another method. When testing, you can create instances of Mapping_Object__History records and pass these directly to that method also. Thus the only code that you can't test is the actual query (although the query might succeed, I can't really remember what happened with that).
Thanks a lot for the solution Bob. It worked!!
Can anyone provide detailed solution on this as I am struggling with it long time?