How to write an advanced test class for an advanced trigger?

If you’re reading this article, I understand you has already been exposed to the basic concepts of Salesforce triggers, test classes and the best practices related to it, right?

If you’re not familiar with these patterns, take a look:


  • Don’t forget that trigger handle up to 200 records per execution.
  • Don’t put the logic (incl. SOQL or DML) in the trigger, use a handler class.
  • Don’t push the trigger.New logic to the handler class method, you should filter on records that are in related scope. You will increase performance, reduce governor limits consumption, and limit regression risks when updating the class.
  • Create one trigger per event and per object. Multiple triggers for the same event of an object would not ensure that the execution order would always be the same, giving unpredictable behavior in production. Managing multiple events in the same trigger would reduce maintainability with spaghetti code.
  • Put bypass logic in the trigger for each handler class. This would prevent running some code for some users. For instance, a technical user doing data migration will have improved performance if some business logic is not triggered. For this purpose, you should use PAD framework. Ensure that each bypass keyword used in triggers is defined in the bypass multi-picklist definition.

Test Classes

  • Prefer creating multiple testMethods in a test class instead of one big method. Benefit is maintainability
  • Avoid using seealldata=true in test classes to avoid conflict (locking contention) with real production data
  • Always assert() in test methods
  • Leverage a @testSetup method to reduce execution time and increase maintainability
  • Test the limits (bulk)
  • Use test.startTest() after data preparation and test.stopTest() before asserts
  • It is better to do Test Driven Development. It is more productive development.
  • Prefer target 85% code coverage per class

Well, imagine now you have to create a bulkified trigger to Automate Maintenance Requests (cases) of a recreational vehicle rental company. One hard truth is that all parts of a vehicle eventually need servicing. You’ll build a programmatic process that automatically schedules regular checkups on these parts based on the date that the equipment and parts were installed. When an existing maintenance request of type Repair or Routine Maintenance is Closed, you create a new maintenance request for a future routine checkup.

The logic needs to be exposed for other uses in the org, so separate the trigger (named MaintenanceRequest) from the application logic in the handler (named MaintenanceRequestHelper). This setup makes it easier to delegate actions and simpler to extend the app in the future.

In this context, you trigger could look like this:

And how the Handler class would look like, based on our requirements:

Now we need to test this trigger. The following test class will do the trick:

That’s it. Now you’re prepared to create an advanced trigger, that uses several good practices and has a Handler Class. You also learned how to create an advanced test class for this trigger. Always remember to use the Design Patterns.

And, if necessary, save this post for your future reference.

I hope you find this useful. See you next time.