実は ApexクラスでHTTP Calloutsの処理をするクラスに対して
普通にテストクラスを作って
実行すると次のようなエラーが発生して処理がスキップされてしまいます。
HTTP Calloutsのテストクラスを作成するには"HttpCalloutMock"を実装した
クラスが必要です。
これを用意しテストクラス内で
次のような宣言で呼び出すことで擬似的な
HTTP Calloutsの結果を取得することができるとのことです。
Test.setMock(HttpCalloutMock.class, new YourImplementsHttpCalloutMockClass());
今回、郵便番号検索機能を例にしたテストクラスを
共有したいと思います
目次
ZipCloudのhttp calloutsのテスト
zipCloudのクラス例をテストするにはまず
sfdc側が用意した「HttpCalloutMock」を実装したMockクラスを作成する必要がある
zipCloudのクラス例
public with sharing class SearchByZipCode{ /** * get JSON Data From Google Api By PostalCode * 郵便番号でグーグルAPIから住所データを取得 * @param String postalCD 郵便番号 * @return JSON Data 取得したJson */ public static String getJSONByPostCD(String zipcode){ Http http = new Http(); HttpRequest req = new HttpRequest(); HttpResponse res = new HttpResponse(); List<String> zipcodeFormat = new String[]{zipcode}; String url = 'http://zipcloud.ibsnet.co.jp/api/search?zipcode='; req.setHeader('Content-Type', 'application/json'); req.setHeader('Accept','application/json'); req.setEndpoint(url); req.setMethod('GET'); req.setTimeout(20000); Boolean isError = false; try{ res = http.send(req); }catch(System.CalloutException ce){ isError = true; return ce.getMessage(); } return res.getBody(); } }
「HttpCalloutMock」を実装したMockクラス例
1データ、個人的にあまり好きではないため、2データ用意した(笑)
@isTest public class ZipCloudCalloutMock implements HttpCalloutMock { // エラー発生フラグ public Boolean errorFlg { get; set; } /** * @description コンストラクタ * @param errFlg エラー発生フラグ * */ public ZipCloudCalloutMock(Boolean errFlg) { this.errorFlg = errFlg; } public HTTPResponse respond(HTTPRequest request) { // エラーフラグがtrueだった場合は通信エラーを投げる if (this.errorFlg) { throw new System.CalloutException('通信エラー'); } // create fake data map Map<String, Object> responseMap = createFakeData(); // Create a fake response HttpResponse response = new HttpResponse(); response.setHeader('Content-Type', 'application/json'); response.setBody(JSON.serialize(responseMap)); response.setStatusCode(200); return response; } // create fake data map private Map<String, Object> createFakeData(){ // fake data list List<Object> addDataList = new List<Object>(); // fake data map Map<String, Object> responseMap = new Map<String, Object>(); // fake data 1 Map<String, String> addData1Map = new Map<String, String>(); addData1Map.put('address1', '愛知県'); addData1Map.put('address2', '清須市'); addData1Map.put('address3', '春日県'); addData1Map.put('kana1', 'アイチケン'); addData1Map.put('kana2', 'キヨスシ'); addData1Map.put('kana3', 'ハルヒアガタ'); addData1Map.put('prefcode', '23'); addData1Map.put('zipcode', '4520962'); // Store data1 into data list addDataList.add(addData1Map); // fake data 1 Map<String, String> addData2Map = new Map<String, String>(); addData2Map.put('address1', '愛知県'); addData2Map.put('address2', '清須市'); addData2Map.put('address3', '春日江先'); addData2Map.put('kana1', 'アイチケン'); addData2Map.put('kana2', 'キヨスシ'); addData2Map.put('kana3', 'ハルヒエサキ'); addData2Map.put('prefcode', '23'); addData2Map.put('zipcode', '4520962'); // Store data2 into data list addDataList.add(addData2Map); responseMap.put('message', null); responseMap.put('results', addDataList);// data list put in data map responseMap.put('status', 200); return responseMap; } }
Http Calloutsのテスト
上記で作成したMockクラス:ZipCloudCalloutMockを用いてテストクラスを作成
@IsTest private class SearchByZipCodeTest{ static testMethod void search_Normal_Test() { String testZipcode = '4520962'; Test.startTest(); Test.setMock(HttpCalloutMock.class, new ZipCloudCalloutMock(false)); String result = SearchByZipCode.getJSONByPostCD(testZipcode); System.debug('call out result-ok:' + result); Test.stopTest(); } static testMethod void search_Abnormal_Test() { String testZipcode = '4520962'; Test.startTest(); Test.setMock(HttpCalloutMock.class, new ZipCloudCalloutMock(true)); String result = SearchByZipCode.getJSONByPostCD(testZipcode); System.debug('call out result-no:' + result); Test.stopTest(); } }
まとめ
Webserviceを使ったクラスのテストを実装するには
手順が下記通り
1:「HttpCalloutMock」を実装したカスタムのMockクラスを作成し、疑似テストデータを用意する
2:「Http」をコールしたクラスのテストクラスを作成し、中に
「1」で用意したカスタムMockクラスを下記のようにコールする
Test.setMock(HttpCalloutMock.class, new カスタムMockクラス(引数がある場合設定));
静的リソースを使用したテストもある、次回、共有します。