5.2 Write unit test for a trigger

Now let’s write a unit test for an Apex trigger. As for the example, let’s use the Apex trigger mentioned in Chapter 3.2. The trigger code is as below:

trigger MerchandiseTrigger on Merchandise__c (before insert) {
    for(Merchandise__c mer: Trigger.New) {
        if(mer.Discount_Type__c == 'Normal price') {
            mer.Discounted_Price__c = mer.Original_Price__c;
        else if (mer.Discount_Type__c == 'Good price') {
            mer.Discounted_Price__c = mer.Original_Price__c * 0.7;
        } else if (mer.Discount_Type__c == 'Half price') {
            mer.Discounted_Price__c = mer.Original_Price__c * 0.5;

The code

Below is the unit test code:

public class TestMerchandiseTrigger {
    public static void testDiscountPrice() {
        Merchandise__c mer1 = new Merchandise__c();
        mer1.Original_Price__c = 100;
        mer1.Discount_Type__c = 'Normal price';

        Merchandise__c mer2 = new Merchandise__c();
        mer2.Original_Price__c = 100;
        mer2.Discount_Type__c = 'Good price';

        Merchandise__c mer3 = new Merchandise__c();
        mer3.Original_Price__c = 100;
        mer3.Discount_Type__c = 'Half price';

        List<Merchandise__c> merList = new List<Merchandise__c> {mer1, mer2, mer3};
        insert merList;

        merList = [Select Id, Discounted_Price__c From Merchandise__c];
        for(Merchandise__c mer: merList) {
            if(mer.Id == mer1.Id) {
                System.assertEquals(mer.Discounted_Price__c, 100); 
            if(mer.Id == mer2.Id) {
                System.assertEquals(mer.Discounted_Price__c, 70); 
            if(mer.Id == mer3.Id) {
                System.assertEquals(mer.Discounted_Price__c, 50); 

Run the unit test and you can find it should pass and the test coverage should be 100%.

Some explanations

There are several things to take care of in this unit test:

  1. Salesforce test code use a separate data partition than normal database. So you don’t have access to any actual data in your unit tests. You need to generate them by yourself. Unless you choose to use seeAllData=true annotation which I suggest you should never use. See why not to use (SeeAllData == true). And test data won’t have actual impact to normal database. The test data will be wiped once the test execution is completed.
  2. The test data for each test method is also separate. So if you have several test methods, you need to generate test data for each method.
  3. Once you insert data into database, the SObject record doesn’t automatically update the fields’ value because of the trigger – so you need to re-query. The only thing which will be automatically populated is the Id field value.

Next Post

5.3 TestVisible and TestSetup Annotation

Subscribe to Sfdcinpractice

Subscribe to get the latest blogs and tutorials of sfdcinpractice. No spam, no trash, only the awesome posts from sfdcinpractice. 

Leave a Reply

Your email address will not be published / Required fields are marked *