Apex 公開コールバックのテスト
Apex テストでは、イベントメッセージがテストイベントバスで同期的に公開されます。テストでコールバックメソッドの実行をシミュレートするため、イベントメッセージを配信したり、イベントメッセージの公開を失敗させたりします。
1 つのイベントまたはイベントのバッチを公開するときの失敗をシミュレートするには、次のメソッドをコールします。
1Test.getEventBus().fail();Test.getEventBus().fail() メソッドを使用すると、コールの直後にイベントの公開が失敗し、イベントメッセージがテストイベントバスから削除されます。このメソッドでは、コールバッククラスの onFailure() メソッドが呼び出されます。イベントメッセージを公開できない場合は、プラットフォームイベントで定義されているどのトリガも、失敗したイベントを受信しません。
イベント配信の成功をシミュレートするには、Test.getEventBus().deliver(); メソッドをコールするか、Test.stopTest() の後にイベントを配信します。イベントメッセージは、それらの各ステートメントの直後に配信されます。イベント配信が成功すると、コールバッククラスの onSuccess() メソッドの実行がトリガされます。
例: MyCallbackTest テストクラス
次のクラスの例は、前述した FailureAndSuccessCallback クラスのテストクラスです。このテストクラスは、テストイベントメッセージをテストイベントバスで公開するときの成功と失敗をテストする方法を示しています。このテストクラスを実行する前に、[設定] で表示ラベルの Order Event と Order Id の Text(18) 項目を指定して、プラットフォームイベントを定義します。
1@isTest
2public class MyCallbackTest {
3 @isTest static void testFailedEventsWithFail() {
4
5 // Publish with callback
6 FailureAndSuccessCallback cb = new FailureAndSuccessCallback();
7
8 // Create test event with EventUuid field value
9 Order_Event__e event = (Order_Event__e)Order_Event__e.sObjectType.newSObject(null, true);
10 event.Order_Id__c='100';
11 System.debug('EventUuid of created event: ' + event.EventUuid);
12 // Publish an event with callback
13 EventBus.publish(event, cb);
14
15 // Fail event
16 // (invoke onFailure and DO NOT deliver event to subscribers)
17 Test.getEventBus().fail();
18
19 // Verify that tasks were created by the onFailure() method
20 List<Task> tasksFailed =
21 [SELECT Id,Subject,Description FROM Task
22 WHERE Subject='Follow up on event publishing failures.'];
23 System.Assert.areEqual(1,tasksFailed.size(),
24 'Unexpected number of tasks received for failed publishing');
25 System.debug('tasksFailed[0].Description=' + tasksFailed[0].Description);
26 System.debug('event.EventUuid=' + event.EventUuid);
27 System.Assert.isTrue(tasksFailed[0].Description.contains(event.EventUuid),
28 'EventUuid was not found in the Description field.');
29
30 }
31
32 @isTest static void testSuccessfulEventsWithDeliver() {
33
34 // Publish with callback
35 FailureAndSuccessCallback cb = new FailureAndSuccessCallback();
36
37 // Create test event with EventUuid field value
38 Order_Event__e event = (Order_Event__e)Order_Event__e.sObjectType.newSObject(null, true);
39 event.Order_Id__c='99';
40 // Publish an event with callback
41 EventBus.publish(event, cb);
42
43 // Deliver events published so far
44 // (invokes onSuccess and delivers events to subscribers)
45 Test.getEventBus().deliver();
46
47 // Verify that tasks were created by the onSuccess() method
48 List<Task> tasksSuccessful =
49 [SELECT Id,Subject,Description FROM Task
50 WHERE Subject='Follow up on successful event publishing.'];
51 System.Assert.areEqual(1,tasksSuccessful.size(),
52 'Unexpected number of tasks received for successful publishing');
53 System.Assert.isTrue(tasksSuccessful[0].Description.contains(event.EventUuid),
54 'EventUuid was not found in the Description field.');
55
56 }
57
58 @isTest static void testSuccessfulEventsWithStopTest() {
59
60 // Start test
61 Test.startTest();
62
63 // Publish with callback
64 FailureAndSuccessCallback cb = new FailureAndSuccessCallback();
65
66 // Create test event with EventUuid field value
67 Order_Event__e event = (Order_Event__e)Order_Event__e.sObjectType.newSObject(null, true);
68 event.Order_Id__c='99';
69 // Publish an event with callback
70 EventBus.publish(event, cb);
71
72 // After the test ends, it delivers the events published
73 // (invokes onSuccess and delivers to subscribers)
74 Test.stopTest();
75
76 // Verify that we have two tasks created by the onSuccess() method:
77 // one task from the earlier deliver() call and one event after Test.stopTest()
78 List<Task> tasksSuccessful =
79 [SELECT Id,Subject,Description FROM Task
80 WHERE Subject='Follow up on successful event publishing.'];
81 System.Assert.areEqual(1,tasksSuccessful.size(),
82 'Unexpected number of tasks received for successful publishing');
83 System.Assert.isTrue(tasksSuccessful[0].Description.contains(event.EventUuid),
84 'EventUuid was not found in the Description field.');
85 }
86}例: MyCallbackTestWithCorrelation テストクラス
次のクラスの例は、前述した FailureCallbackWithCorrelation クラスのテストクラスです。このテストクラスは、テストイベントメッセージをテストイベントバスで公開するときの失敗をテストする方法を示しています。コールバックでは、イベントの公開が最大 2 回再試行されます。そのため、テストでは、テストイベントの公開が 1 回のループで 2 回失敗します。テストでは、毎回コールバックが retryCounter 変数の増加を確認してイベントの公開を再試行することが検証されます。このテストクラスを実行する前に、[設定] で表示ラベルの Order Event と Order Id の Text(18) 項目を指定して、プラットフォームイベントを定義します。
1@isTest
2public class MyCallbackTestWithCorrelation {
3
4 @isTest
5 static void testFailedEventsWithFail() {
6 // Create test event
7 Order_Event__e event = (Order_Event__e)Order_Event__e.sObjectType.newSObject(null, true);
8 event.Order_Id__c='dummyOrderId';
9
10 // Populate map
11 Map<String,String> uuidMap = new Map<String,String>();
12 uuidMap.put(event.EventUuid, 'dummyOrderId');
13
14 // Create callback
15 FailureCallbackWithCorrelation cb = new FailureCallbackWithCorrelation(uuidMap);
16
17 // Make sure retry counter is 0
18 Assert.areEqual(0, cb.getRetryCounter(),
19 'Newly created callback should have retry counter at 0');
20
21 // Publish an event with callback
22 EventBus.publish(event, cb);
23
24 // If we fail all publish attempts, callback should run MAX_RETRIES times.
25 // For each attempt, the callback should republish the event, increase the counter, and update the map
26 String prevUuid = event.EventUuid;
27 for (Integer i = 1; i <= FailureCallbackWithCorrelation.MAX_RETRIES; i++) {
28 Test.getEventBus().fail();
29 Assert.areEqual(i, cb.getRetryCounter(), 'Retry counter should be ' + i);
30 Assert.areEqual(1, cb.getUuidMap().size(), 'Map size should be 1');
31 String currUuid = (new List<String>(cb.getUuidMap().keySet())).get(0);
32 Assert.areNotEqual(prevUuid, currUuid,
33 'Map should be updated with newly created event Uuid');
34 Assert.areEqual('dummyOrderId', cb.getUuidMap().get(currUuid),
35 'Map value should be the original Order Id');
36 prevUuid = currUuid;
37 }
38
39 // If we publish another failed event, callback should not retry.
40 Order_Event__e event2 = (Order_Event__e)Order_Event__e.sObjectType.newSObject(null, true);
41 event2.Order_Id__c='dummyOrderId';
42 EventBus.publish(event, cb);
43 Test.getEventBus().fail();
44 Assert.areEqual(FailureCallbackWithCorrelation.MAX_RETRIES, cb.getRetryCounter(),
45 'Retry counter should still be ' +
46 FailureCallbackWithCorrelation.MAX_RETRIES);
47 }
48}