Test Change Event Triggers

Before you can package or deploy Apex change event triggers to production, you must provide Apex tests and sufficient code coverage.

Enable All Change Data Capture Entities for Notifications

To enable the generation of change event notifications for all supported Change Data Capture entities for an Apex test, call this method.

1Test.enableChangeDataCapture();

Call the Test.enableChangeDataCapture() method at the beginning of your test method before performing DML operations and calling Test.getEventBus().deliver() or Test.stopTest().

The Test.enableChangeDataCapture() method ensures that Apex tests can fire change event triggers regardless of the entities selected in Setup. This method doesn’t affect the Change Data Capture entity selections for the org.

Deliver Test Change Events

To test your change event trigger, perform DML operations and then call the Test.getEventBus().deliver() method. The method delivers the event messages from the test event bus to the corresponding change event trigger and causes the trigger to fire. Finally, validate that the trigger executed as expected. For example, if the trigger creates or updates records, you can query those records with SOQL.

This test method outlines the order of statements that must be executed in a test, starting with enabling Change Data Capture entities.

1@isTest static void testChangeEventTrigger() {
2    // Enable all Change Data Capture entities for notifications.
3    Test.enableChangeDataCapture();
4    
5    // Insert one or more test records
6    // ...
7    
8    // Deliver test change events
9    Test.getEventBus().deliver();
10    
11    // Verify the change event trigger’s execution
12    // ...
13}

Alternatively, use the Test.startTest(), Test.stopTest() method block to fire a change event trigger. After Test.stopTest() executes, all test change event messages generated from DML operations are delivered to the associated trigger. The DML statements can be within the block or outside the block as long as they precede Test.stopTest().

1@isTest static void testChangeEventTriggerWithStopTest() {
2    // Enable all Change Data Capture entities for notifications.
3    Test.enableChangeDataCapture();
4    
5    Test.startTest();
6    // Insert one or more test records
7    // ...
8    Test.stopTest();
9    // The stopTest() call delivers the test change events and fires the trigger
10    
11    // Verify the change event trigger’s execution
12    // ...
13}

In test context, only up to 500 change event messages can be delivered as a result of record changes. If you exceed this limit, the Apex test stops execution with a fatal error.

Note

Apex Test Example Based on Quick Start Trigger

The testNewAccount method in this test class shows you how to write a test for the MyAccountChangeTrigger trigger provided in the Add an Apex Trigger quick start. The test method first enables all entities for change notifications. It creates a test account and then calls the Test.getEventBus().deliver(); method. Next, the test verifies that the trigger’s execution by querying Task records and validating that one task was created. The query returns only tasks that the trigger created in test contest. For that reason, the test expects only one task. Next, the test updates the account and verifies that no new task is created.

1@isTest
2public class TestMyAccountChangeTrigger {
3    @isTest static void testNewAndUpdatedAccount() {
4        // Enable all Change Data Capture entities for notifications.
5        Test.enableChangeDataCapture();
6
7        // Insert an account to generate a change event. 
8        Account newAcct = new Account(Name='TestAccount', Phone='4155551212'); 
9        insert newAcct;
10        
11        // Call deliver to fire the trigger and deliver the test change event.
12        Test.getEventBus().deliver();
13        
14        // VERIFICATIONS
15        // Check that the change event trigger created a task.
16        Task[] taskList = [SELECT Id,Subject FROM Task];        
17        System.assertEquals(1, taskList.size(),
18            'The change event trigger did not create the expected task.');
19            
20        // Update account record
21        Account queriedAcct = [SELECT Id,Phone,Website FROM Account WHERE Id=:newAcct.Id];
22        // Debug
23        System.debug('Retrieved account record: ' + queriedAcct);
24        // Update one field and empty another
25        queriedAcct.Website = 'www.salesforce.com';
26        queriedAcct.Phone = null;
27        update queriedAcct;
28        
29        // Call deliver to fire the trigger for the update operation
30        Test.getEventBus().deliver();
31        
32        // VERIFICATIONS
33        // Check that the change event trigger did NOT create a task.
34        // We should still have only 1 task.
35        Task[] taskList2 = [SELECT Id,Subject FROM Task];
36        System.assertEquals(1, taskList2.size(),
37            'The change event trigger created a task unepextedly.');
38    }    
39}

This test class is an alternative example that uses the Test.startTest(), Test.stopTest() method block to deliver test change events and fire the trigger. For more information about these methods, see Using Limits, startTest, and stopTest in the Apex Developer Guide.

1@isTest
2public class TestMyAccountChangeTriggerWithStopTest {
3  @isTest static void testNewAccount() {
4    // Enable all Change Data Capture entities for notifications.
5    Test.enableChangeDataCapture();
6
7    Test.startTest();
8    // Insert an account to generate a change event.
9    insert new Account(Name='TestAccount', Phone='4155551212');
10    Test.stopTest();
11    // The stopTest() call fires the trigger with the test account change event.
12
13    // VERIFICATIONS
14    // Check that the change event trigger created a task.
15    Task[] taskList = [SELECT Id,Subject FROM Task];        
16    System.assertEquals(1, taskList.size(),
17        'The change event trigger did not create the expected task.');
18  }   
19}

If multiple DML operations are performed on a single record within the Test.startTest(), Test.stopTest() block, only one change event is generated. The change event contains the latest data and the initial change type. For more information, see Change Event Generation in a Transaction with Multiple Changes for the Same Record.

Note

Properties of Change Events in Test Context

Test change events messages are published to the test event bus, which is separate from the Salesforce event bus. They aren’t persisted in Salesforce and aren’t delivered to event channels outside the test class. Properties of test change event messages, like the replay ID, are reset in test context and reflect only the values of test event messages. For more information, see Event and Event Bus Properties in Test Context in the Platform Events Developer Guide.