1

I wrote a trigger to prevent the deletion of a record. And also I'm writing test class.

public class ClassA
    public static void preventDelete(List<Person__c> pers) { 
            for(Person__c per: pers) {
                if(per.hasJob__c == true) {
                    rra.addError('You cannot delete the record.');
                }
            }       
    }
}

On trigger:

trigger PersonTrigger on Person__c (before delete) {
        if(trigger.isDelete) {
            if (trigger.isBefore){
                ClassA.preventDelete(trigger.old);
            }
        }
}

But I'm thinking that I can write test class for this trigger by calling the method directly e.g: ClassA.preventDelete(myList); or by creating records on test class then check if it was successfully deleted or not. Then what is the difference between the two and which one is better?

Example 1:

 @isTest
    public class ClassATest {
       public static testMethod void TestPreventDelete() {   
          Person__c p1 = new Person__c(Name='Joseph', hasJob__c=true);

          List<Person__c > pers = new List<Person__c>();
          pers.add(p1);
          insert pers;               

          ClassA.preventDelete(pers); // test class by calling the method of a class 
    
       }
    }

Example 2:

@isTest
    public class ClassATest {
       public static testMethod void TestPreventDelete() {   
          Person__c p1 = new Person__c(Name='Joseph', hasJob__c=true);
          insert p1;
     
          // test class by using dml statement
          Database.DeleteResult result = Database.delete(p1, false);
          System.assert(!result.isSuccess());

       }
    }

2 Answers 2

2

In a setup like this, calling by DML gets you both trigger and class coverage, which saves you from writing an extra few lines of code. In other words, while one is technically better, it really doesn't matter.

What does matter is when you have complicated methods and you want to be able to test individual features of a trigger separately, or be able to disable triggers for some unit tests or while setting up test data, etc.

You'll always need at least one "real DML" just to satisfy code coverage, but the individual parts of the trigger logic can be separated out into separate tests without running the trigger multiple times, allowing for much better performance as your code base expands in size.

Note that DMLs tend to dominate the runtime of unit test run times, so minimizing the number of DML operations you need to make (e.g. by only calling the various methods of the handler directly) will directly improve the lifecycle of your development process, reduce deployment/build times, etc.

Ideally, you should only need to perform up to 4 DML per trigger per object (insert, update, delete, maybe undelete) for trigger code coverage, and the actual methods can be tested with records that don't necessarily exist in the database.

In other words, neither one is better, that's a false dichotomy. You can, and should, use both as the situation arises. Inside the unit test themselves, triggers should be called as necessary, and classes should be called when necessary. The balance will be that point where all your tests run, all the code is covered, and there's not much in wasted DML operations.

1
  • 2
    You obliquely mention it, but I would want to emphasise that you should minimise the number of tests that actually insert data into the database in order to improve performance of the entire unit test suite. As you code base, and thus unit test suite, gets bigger, performance becomes more and more important in order to avoid slowing down development.
    – Phil W
    Commented Jan 6, 2023 at 7:18
1

In the first scenario you are calling directly the method of the apex class from test class which means you are directly checking the functionality of the Apex class but not the Trigger.

In the second scenario you are not calling any method as the Trigger is on delete it is automatically calling the trigger and then the apex class which is our main functionality scenario and also this is what we need to check in the test class.

The another advantage in second scenario is that it also covers Trigger coverage as well which is needed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .