この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

テストイベントメッセージの配信

Test.stopTest() ステートメントの後でテストイベントメッセージを配信します。または、任意の時点で Test.getEventBus().deliver() メソッドを使用してテストイベントメッセージを配信します。Test.getEventBus().fail() メソッドを使用して、テストイベントメッセージを失敗させます。

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();

また、Test.startTest()Test.stopTest() のステートメントブロックの外にある Apex テストメソッドで、Test.getEventBus().deliver() を呼び出すことができます。これにより、非同期 Apex でイベントメッセージをテストできます。

1Test.startTest();
2// Do some tests
3Test.stopTest();
4
5// Deliver test events
6Test.getEventBus().deliver();

非同期 Apex から公開されたテストイベントメッセージの配信

失敗時に BatchApexErrorEvent を公開する一括処理 Apex ジョブをテストする場合は、Test.startTest() および Test.stopTest() のステートメントブロックで Test.getEventBus().deliver() を使用します。Test.stopTest() のコールにより、このステートメントの後に非同期の Apex ジョブを実行できます。次に、Test.getEventBus().deliver() によって、失敗した一括処理ジョブが公開したイベントメッセージを配信できます。

このスニペットは、Apex の一括処理ジョブを実行し、イベントメッセージを配信する方法を示しています。これは Test.stopTest() の後で一括処理ジョブを実行します。この一括処理ジョブは、Database.RaisesPlatformEvents の実装により、失敗が発生すると BatchApexErrorEvent メッセージを公開します。Test.stopTest() が実行された後に、別の Test.getEventBus().deliver() ステートメントが追加され、BatchApexErrorEvent を配信できるようになります。

1try {
2    Test.startTest();
3    Database.executeBatch(new SampleBatchApex());
4    Test.stopTest();
5    // Batch Apex job executes here
6} catch(Exception e) {
7    // Catch any exceptions thrown in the batch job
8}
9
10// The batch job fires BatchApexErrorEvent if it fails, so deliver the event.
11Test.getEventBus().deliver();

非同期 Apex では、キュー可能 Apex や future メソッドも使用できます。この非同期 Apex ジョブ内からプラットフォームイベントメッセージを公開する場合、非同期 Apex ジョブは Test.stopTest() の後に実行します。Test.getEventBus().deliver(); を追加する必要はありません。次の例では、キュー可能 Apex ジョブで公開するプラットフォームイベントメッセージの配信方法を示しています。Test.stopTest() の後、キュー可能ジョブが実行され、イベントメッセージが配信されます。

1Test.startTest();
2System.enqueueJob(new SampleQueueableApex());
3Test.stopTest();
4// Queueable Apex job executes here.
5// The platform event message published by the job is delivered too.

下流のプロセスでさらにプラットフォームイベントが公開される場合は、Test.getEventBus().deliver(); を追加して、それぞれのプロセスでイベントメッセージを配信します。たとえば、Apex ジョブからのイベントを処理するプラットフォームイベントトリガーが、別のプラットフォームのイベントを公開する場合、Test.getEventBus().deliver(); ステートメントを追加してイベントメッセージを配信します。

メモ

例: イベントメッセージの個別配信

このテストクラスは Order_Event__e イベントメッセージを公開し、Test.getEventBus().deliver() を使用してそのイベントメッセージを配信します。また、トリガーでイベントメッセージが処理されてタスクが作成されたことを検証します。重複するイベントメッセージ (同じ Event_ID__c カスタム項目値を持つイベント) が公開され、配信されます。このテストでは、トリガーで重複イベントのタスクが作成されなかったことを検証します。

このテストクラスを実行する前に、Order_Event__e という名前のプラットフォームイベントと、Text 型の Event_ID__c 項目、Text 型の Order_Number__c 項目、Checkbox 型の Has_Shipped__c 項目を定義します。また、OrderTrigger トリガーでも SOQL クエリのユーザーの Name 項目値を John Smith などの Salesforce 組織でのユーザーの氏名に置き換えます。

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 イベントメッセージを処理します。

このトリガーは、受信したイベント通知ごとに SOQL クエリを実行するため、SOQL クエリの Apex ガバナ制限に達する場合があります。

メモ

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='<Replace with FirstName LastName>' 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 tasks in the list.
26    if (tasks.size() > 0) {
27        insert tasks;
28    }
29
30}

Apex 公開コールバックのテストのためにイベントメッセージの公開を失敗させ��

Apex 公開コールバックには、非同期の EventBus.publish コールの最終結果が含まれています。Apex 公開コールバッククラスをテストするため、Test.getEventBus().fail() を使用して、公開コールの失敗をシミュレートします。

Apex テストでは、イベントメッセージがテストイベントバスで同期的に公開されます。テストでコールバックメソッドの実行をシミュレートするため、イベントメッセージを配信したり、イベントメッセージの公開を失敗させたりします。このセクションでは、イベント公開の失敗について説明します。

Test.getEventBus().fail() メソッドを使用すると、コールの直後にイベントの公開が失敗し、イベントメッセージがテストイベントバスから削除されます。このメソッドでは、コールバッククラスの onFailure() メソッドが呼び出されます。イベントメッセージを公開できない場合は、プラットフォームイベントで定義されているどのトリガーも、失敗したイベントを受信しません。

次に示すクラスの例は、「Apex 公開コールバックを使用した非同期プラットフォームイベント公開の結果の取得」に示されている FailureAndSuccessCallback クラスのテストクラスです。このテストクラスは、テストイベントメッセージをテストイベントバスで配信するときの失敗をテストする方法を示しています。このテストクラスを実行する前に、[設定] で表示ラベルの Order EventOrder Number の Text 項目を指定して、プラットフォームイベントを定義します。

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_Number__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}

イベントメッセージを正常に配信するには、次のセクションを確認してください。