はじめに
Apexから外部システムにリクエストを送ることを「コールアウト」といいます。
結構前に実装したことはあるのですが、
テストコードは書いたことがなかったので、調べてみました。
結論
- HttpCalloutMock インターフェースを実装したクラスを作る
- 疑似レスポンスを返すメソッドを実装する
詳細
HttpCalloutMock インターフェースを実装したクラスを作る
- 実装クラスは
global
かpublic
- クラスには
@isTest
をつけよう
サンプルコード)
@isTest
global class YourHttpCalloutMockImpl implements HttpCalloutMock {
global HTTPResponse respond(HTTPRequest req) {
}
}
疑似レスポンスを返すメソッド(respond)を実装する
サンプルコード)
@isTest
global class MockHttpResponseGenerator implements HttpCalloutMock {
global HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
res.setBody('{"example":"test"}');
res.setStatusCode(200);
return res;
}
}
テストコードでTest.setMock()を使いレスポンスを設定
テストコード実行前に以下を書きます。
Test.setMock(HttpCalloutMock.class, new HttpCalloutMockインターフェースの実装クラス());
サンプルコード)
@isTest
private class CalloutClassTest {
@isTest static void testCallout() {
Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
HttpResponse res = CalloutClass.getInfoFromExternalService();
String contentType = res.getHeader('Content-Type');
System.assert(contentType == 'application/json');
String actualValue = res.getBody();
String expectedValue = '{"example":"test"}';
System.assertEquals(actualValue, expectedValue);
System.assertEquals(200, res.getStatusCode());
}
}
その他
- 静的リソースを使って疑似レスポンスを設定する方法もある
- コールアウトの前にDMLを発行したい場合は、コールアウト部分をTest.startTest()とTest.stopTest()で囲う
サンプルコード)
@isTest
private class CalloutClassTest {
@isTest static void testCallout() {
Account testAcct = new Account('Test Account');
insert testAcct;
Test.startTest();
Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
HttpResponse res = CalloutClass.getInfoFromExternalService();
String contentType = res.getHeader('Content-Type');
System.assert(contentType == 'application/json');
String actualValue = res.getBody();
String expectedValue = '{"example":"test"}';
System.assertEquals(actualValue, expectedValue);
System.assertEquals(200, res.getStatusCode());
Test.stopTest();
}
}