テストイベントメッセージの配信
Test.stopTest() の後でテストイベントメッセージを配信
Apex テストでプラットフォームイベントを公開するには、publish ステートメントを Test.startTest() ステートメントと Test.stopTest() ステートメントで囲みます。EventBus.publish() メソッドを Test.startTest() ステートメントと Test.stopTest() ステートメントの間でコールします。テストコンテキストでは、EventBus.publish() メソッドは公開操作をキューに追加します。Test.stopTest() ステートメントは、イベントの公開を実行し、イベントメッセージをテストイベントバスに配信します。Test.stopTest() ステートメントの後に検証を含めます。たとえば、登録された Apex トリガまたは登録されたフローの待機要素によって、Salesforce レコードの作成など、期待されるアクションが実行されたかどうかを検証できます。
1// Create test events
2Test.startTest();
3// Publish test events with EventBus.publish()
4Test.stopTest();
5// Perform validations例
次のサンプルテストクラスには 2 つのテストメソッドが含まれます。testValidEvent() メソッドは、イベントの公開が成功し、関連付けられたトリガが起動されたかどうかを確認します。testInvalidEvent() メソッドは、必須項目の欠落したイベントの公開が失敗してトリガが起動されないことを検証します。testValidEvent() メソッドは、1 つの Low_Ink__e イベントを作成します。Test.stopTest() の後、これは SOQL クエリを実行し、ケースレコードが作成されること、つまりトリガが起動されたことを検証します。2 番目のテストメソッドは同様のプロセスに従いますが、無効なテストを目的とします。
この例では、組織で Low_Ink__e イベントおよび関連付けられたトリガが定義されている必要があります。
1@isTest
2public class EventTest {
3 @isTest static void testValidEvent() {
4
5 // Create a test event instance
6 Low_Ink__e inkEvent = new Low_Ink__e(Printer_Model__c='MN-123',
7 Serial_Number__c='10013',
8 Ink_Percentage__c=0.15);
9
10 Test.startTest();
11
12 // Publish test event
13 Database.SaveResult sr = EventBus.publish(inkEvent);
14
15 Test.stopTest();
16
17 // Perform validations here
18
19 // Verify SaveResult value
20 System.assertEquals(true, sr.isSuccess());
21
22 // Verify that a case was created by a trigger.
23 List<Case> cases = [SELECT Id FROM Case];
24 // Validate that this case was found
25 System.assertEquals(1, cases.size());
26 }
27
28 @isTest static void testInvalidEvent() {
29
30 // Create a test event instance with invalid data.
31 // We assume for this test that the Serial_Number__c field is required.
32 // Publishing with a missing required field should fail.
33 Low_Ink__e inkEvent = new Low_Ink__e(Printer_Model__c='MN-123',
34 Ink_Percentage__c=0.15);
35
36 Test.startTest();
37
38 // Publish test event
39 Database.SaveResult sr = EventBus.publish(inkEvent);
40
41 Test.stopTest();
42
43 // Perform validations here
44
45 // Verify SaveResult value - isSuccess should be false
46 System.assertEquals(false, sr.isSuccess());
47
48 // Log the error message
49 for(Database.Error err : sr.getErrors()) {
50 System.debug('Error returned: ' +
51 err.getStatusCode() +
52 ' - ' +
53 err.getMessage()+' - '+err.getFields());
54 }
55
56 // Verify that a case was NOT created by a trigger.
57 List<Case> cases = [SELECT Id FROM Case];
58 // Validate that this case was found
59 System.assertEquals(0, cases.size());
60 }
61}必要に応じて Test.getEventBus().deliver() を使用してテストイベントメッセージを配信
Test.getEventBus().deliver() をコールすることで、登録者にテストイベントメッセージを配信するタイミングを制御できます。Test.getEventBus().deliver() を使用してテストイベントメッセージを複数回配信し、登録者が各ステップでテストイベントを処理したことを検証します。イベントメッセージを複数回配信することは、イベントの連続的な処理をテストする場合に役立ちます。たとえば、同じテスト内のループで登録者の連続アクションを検証できます。
Test.getEventBus().deliver() を Test.startTest() と Test.stopTest() のステートメントブロックで囲みます。
1Test.startTest();
2// Create test events
3// ...
4// Publish test events with EventBus.publish()
5// ...
6// Deliver test events
7Test.getEventBus().deliver();
8// Perform validations
9// ...
10Test.stopTest();例
このテストクラスは Order_Event__e イベントメッセージを公開し、Test.getEventBus().deliver() を使用してそのイベントメッセージを配信します。また、トリガでイベントメッセージが処理されてタスクが作成されたことを検証します。重複するイベントメッセージ (同じ Event_ID__c カスタム項目値を持つイベント) が公開され、配信されます。このテストでは、トリガで重複イベントのタスクが作成されなかったことを検証します。
このテストクラスを実行する前に、Order_Event__e という名前のプラットフォームイベントと、Text 型の Event_ID__c 項目、Text 型の Order_Number__c 項目、Checkbox 型の Has_Shipped__c 項目を定義します。
1@isTest
2public class MyTestClassDeliver {
3
4 @isTest static void doSomeTesting() {
5
6 Test.startTest();
7
8 // Publish a test event
9 Order_Event__e event = new Order_Event__e(
10 Event_ID__c='123AB', Order_Number__c='12346', Has_Shipped__c=true);
11 Database.SaveResult sr = EventBus.publish(event);
12
13 // Verify that the publish was successful
14 System.assertEquals(true, sr.isSuccess());
15
16 // Deliver the test event before Test.stopTest()
17 Test.getEventBus().deliver();
18
19 // Check that the case that the trigger created is present.
20 List<Task> tasks = [SELECT Id FROM Task];
21 // Validate that this task was found.
22 // There is only one test task in test context.
23 Integer taskCount = tasks.size();
24 System.assertEquals(1, taskCount);
25
26 // Publish a duplicate event
27 Order_Event__e dupEvent = new Order_Event__e(
28 Event_ID__c='123AB', Order_Number__c='12346', Has_Shipped__c=true);
29 Database.SaveResult sr2 = EventBus.publish(dupEvent);
30
31 // Verify that the publish was successful.
32 System.assertEquals(true, sr2.isSuccess());
33
34 Test.getEventBus().deliver();
35
36 // Get all tasks in test context
37 List<Task> tasksNew = [SELECT Id FROM Task];
38 // Validate that no task was created and
39 // the number of tasks should not have changed.
40 System.assertEquals(taskCount, tasksNew.size());
41
42 Test.stopTest();
43
44 }
45}このトリガは、テストクラスで公開する Order_Event__e イベントメッセージを処理します。
1trigger OrderTrigger on Order_Event__e (after insert) {
2 // List to hold all cases to be created.
3 List<Task> tasks = new List<Task>();
4
5 // Get user Id for case owner
6 User usr = [SELECT Id FROM User WHERE Name='Admin User' LIMIT 1];
7
8 // Iterate through each notification.
9 for (Order_Event__e event : Trigger.New) {
10 if (event.Has_Shipped__c == true) {
11 // Create task only if it doesn't exist yet for the same order
12 String eventID = '%' + event.Event_ID__c;
13 List<Task> tasksFromQuery =
14 [SELECT Id FROM Task WHERE Subject LIKE :eventID];
15 if (tasksFromQuery.size() == 0) {
16 Task t = new Task();
17 t.Priority = 'Medium';
18 t.Subject = 'Follow up on shipped order ' + event.Order_Number__c +
19 ' for event ID ' + event.Event_ID__c;
20 t.OwnerId = usr.Id;
21 tasks.add(t);
22 }
23 }
24 }
25 // Insert all cases corresponding to events received.
26 insert tasks;
27
28}