Telling you how to fix your code is MISSING THE POINT: JUST USE A VALIDATION RULEmissing the key takeaway. Just use a validation rule.
ISCHANGED(Subject)
Advantages:
- No need to unit test
- Cannot throw any exceptions
- Easy and quick to change error message
I want to point out some of the issues with your code though so you can avoid them in future projects.
What happens if an end user sets the new Subject
to null
?
System.NullPointerException: Attempt to de-reference a null object
What happens if the production environment does not have a User
with the specified Id? Or if you just want to run your test successfully in a developer environment?
System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, invalid cross reference id: []
I recommend you look at using the Selector library to take care of filtering logic for you.
If you feel you must roll your own filters, you should at least split it out into static
methods and separate the filter logic from the validation logic.
public static List<Event> hasSubjectChanged(List<Event> newEvents, Map<Id, Event> oldMap)
{
List<Event> changed = new List<Event>();
for (Event newEvent : newEvents)
{
if (newEvent.Subject != oldMap.get(newEvent.Id).Subject) changed.add(newEvent);
}
return changed;
}
public static void validateSubjectChange(List<Event> invalidEvents)
{
for (Event invalidEvent : invalidEvents)
invalidEvent.addError('Cannot change Subject Field');
}
These methods would be easy to call from your trigger:
validateSubjectChange(hasSubjectChanged(trigger.new, trigger.oldMap));
If you use Selector:
validateSubjectChange(
Select.Field.hasChanged(Event.Subject).filter(trigger.new, trigger.oldMap)
);