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

DML 操作と擬似コールアウトの実行

デフォルトでは、必ず同じトランザクション内で DML 操作の後にコールアウトを実行することは許可されません。これは DML 操作によって、コミットされていない待機中の作業が発生してコールアウトの実行が妨げられるためです。場合によっては、コールアウトを行う前に、DML を使用してテストメソッドにテストデータを挿入する必要が生じることがあります。これを行うには、コールアウトを実行するコード部分を Test.startTestTest.stopTest ステートメントの間に配置します。Test.startTest ステートメントは、Test.setMock ステートメントの前に配置する必要があります。また、DML 操作のコールは、Test.startTest/Test.stopTest ブロックの一部にすることはできません。

擬似コールアウト後の DML 操作は許可されており、テストメソッドでの変更は必要ありません。

DML 操作のサポートは、HttpCalloutMock インターフェースおよび静的リソース (StaticResourceCalloutMock または MultiStaticResourceCalloutMock) を使用することで、疑似コールアウトのすべての実装で動作します。次の例では、実装された HttpCalloutMock インターフェースを使用しますが、同じ方法を静的リソースを使用するときにも適用できます。

擬似コールアウト前の DML の実行

この例は、前の HttpCalloutMock の例に基づいています。この例では、Test.startTest および Test.stopTest ステートメントを使用して、テストメソッドで疑似コールアウトの前に DML 操作を実行できるようにします。テストメソッド (testCallout) は最初にテスト取引先を挿入し、Test.startTest をコールします。次に、Test.setMock を使用して疑似コールアウトモードを設定して、コールアウトを実行するメソッドをコールし、疑似応答値を確認します。最後に、Test.stopTest をコールします。

1@isTest
2private class CalloutClassTest {
3     @isTest static void testCallout() {
4        // Perform some DML to insert test data
5        Account testAcct = new Account('Test Account');
6        insert testAcct;
7
8        // Call Test.startTest before performing callout
9        // but after setting test data.
10        Test.startTest();
11
12        // Set mock callout class 
13        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
14        
15        // Call method to test.
16        // This causes a fake response to be sent
17        // from the class that implements HttpCalloutMock. 
18        HttpResponse res = CalloutClass.getInfoFromExternalService();
19        
20        // Verify response received contains fake values
21        String contentType = res.getHeader('Content-Type');
22        System.assert(contentType == 'application/json');
23        String actualValue = res.getBody();
24        String expectedValue = '{"example":"test"}';
25        System.assertEquals(actualValue, expectedValue);
26        System.assertEquals(200, res.getStatusCode());
27
28        Test.stopTest();
29    }
30}

非同期 Apex と擬似コールアウト

DML と同様に、非同期 Apex 操作では、コミットされていない待機中の作業によって、同じトランザクションの後の方でコールアウトの実行が妨げられる結果になります。非同期 Apex 操作の例としては、future メソッド、Apex 一括処理、スケジュール済み Apex のコールがあります。通常、これらの非同期コールは、Test.stopTest の後で実行されるようにするため、テストメソッドで Test.startTestTest.stopTest ステートメント間に配置します。この場合、擬似コールアウトは非同期コールの後で実行できるため、変更は不要です。ただし、非同期コールが Test.startTestTest.stopTest ステートメント間に配置されていない場合は、コミットされていない待機中の作業のため例外が発生します。この例外を回避するには、次のいずれかを行います。
  • 非同期コールを Test.startTestTest.stopTest ステートメント間に配置する。
    1Test.startTest();
    2MyClass.asyncCall();
    3Test.stopTest();
    4
    5Test.setMock(..); // Takes two arguments
    6MyClass.mockCallout();
  • DML コールと同じルールに従う。つまり、コールアウトを実行するコード部分を Test.startTestTest.stopTest ステートメント間に配置します。Test.startTest ステートメントは、Test.setMock ステートメントの前に配置する必要があります。また、非同期コールは、Test.startTest/Test.stopTest ブロックの一部にすることはできません。
    1MyClass.asyncCall();
    2
    3Test.startTest();
    4Test.setMock(..); // Takes two arguments
    5MyClass.mockCallout();
    6Test.stopTest();

擬似コールアウト後の非同期コールは許可されており、テストメソッドでの変更は必要ありません。