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();
}
}
以上の参照先
Testing multiple HTTP callouts
呼び出し先区別のため、下記内容を参照する。
Testing Apex Callouts using HttpCalloutMock | Salesforce Developers Blog
抜粋:
public class ProcessAccountsContacts {
public static String getJSON(String url) {
HttpRequest req = new HttpRequest();
req.setEndpoint(url);
req.setMethod('GET');
Http h = new Http();
HttpResponse res = h.send(req);
return res.getBody();
}
public static Integer processAccountsContacts() {
String jsonData = getJSON('http://api.example.com/accounts');
List accounts =
(List)JSON.deserialize(jsonData, List.class);
jsonData = getJSON('http://api.example.com/contacts');
List contacts =
(List)JSON.deserialize(jsonData, List.class);
// 'Processing'
Integer result = accounts.size() + contacts.size();
return result;
}
}
上記のソースで我々は二つCALLOUTを作成した、呼び出し先区別のため、下記クラスを作成する。
public class MultiRequestMock implements HttpCalloutMock {
Map<String, HttpCalloutMock> requests;
public MultiRequestMock(Map<String, HttpCalloutMock> requests) {
this.requests = requests;
}
public HTTPResponse respond(HTTPRequest req) {
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓呼び出し先の取得↓↓↓↓↓
HttpCalloutMock mock = requests.get(req.getEndpoint());
if (mock != null) {
return mock.respond(req);
} else {
throw new MyCustomException('HTTP callout not supported for test methods');
}
}
public void addRequestMock(String url, HttpCalloutMock mock) {
requests.put(url, mock);
}
}
テストクラスについて、下記を参照してください。
@isTest
public class MultipleCalloutsTest{
public static testmethod void testAcctsAndContactsCallout() {
SingleRequestMock fakeAccountResp = new SingleRequestMock(200,
'Complete',
'[{"Name": "sForceTest1"}]',
null);
SingleRequestMock fakeContactsResp = new SingleRequestMock(200,
'Complete',
'[{"LastName": "Test Last Name"}]',
null);
Map<String, HttpCalloutMock> endpoint2TestResp =
new Map<String,HttpCalloutMock>();
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓呼び出し先の設定↓↓↓↓↓
endpoint2TestResp.put('http://api.example.com/accounts',fakeAccountResp);
endpoint2TestResp.put('http://api.example.com/contacts',fakeContactsResp);
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑呼び出し先の設定↑↑↑↑↑↑↑
HttpCalloutMock multiCalloutMock =
new MultiRequestMock(endpoint2TestResp);
Test.setMock(HttpCalloutMock.class, multiCalloutMock);
ProcessAccountsContacts.processAccountsContacts();
System.assertEquals(/*check for expected results here...*/);
}
}
以上よろしくお願いいたします。