Trailheadに紹介されていたApexとSOAP Calloutsについてです。
まず、下記リンク先からXMLファイルをダウンロードします。
https://th-apex-soap-service.herokuapp.com/assets/calculator.xml
Apexクラスページの「Generate from WSDL」ボタンをクリックします。
先ほどダウンロードしたXMLファイルをアップします。
これでXMLファイルからApexクラスを生成できます。
生成されたApexクラスは次のように利用できます。
public class AwesomeCalculator { public static Double add(Double x, Double y) { calculatorServices.CalculatorImplPort calculator = new calculatorServices.CalculatorImplPort(); return calculator.doAdd(x,y); } }
開発者コンソールなどで次の処理を実行すると正しく動作することを確認できると思います。
Double result = AwesomeCalculator.add(10, 1000); System.debug(result);
テストクラスの実装では次のようなモックを作成します。
@isTest global class CalculatorCalloutMock implements WebServiceMock { global void doInvoke( Object stub, Object request, Map<String, Object> response, String endpoint, String soapAction, String requestName, String responseNS, String responseName, String responseType) { // start - specify the response you want to send calculatorServices.doAddResponse response_x = new calculatorServices.doAddResponse(); response_x.return_x = 3.0; // end response.put('response_x', response_x); } }
あとはそのモックを利用してテストクラスを作成します。
@isTest private class AwesomeCalculatorTest { @isTest static void testCallout() { // This causes a fake response to be generated Test.setMock(WebServiceMock.class, new CalculatorCalloutMock()); // Call the method that invokes a callout Double x = 1.0; Double y = 2.0; Double result = AwesomeCalculator.add(x, y); // Verify that a fake result is returned System.assertEquals(3.0, result); } }
ざっくりですがこんな感じです。
追記
別のパターンも記載しておきます。国名を渡すと公園名が取得できる処理の場合です。
public class ParkLocator { public static String[] getParks(String s) { parksServices.ParksImplPort park = new parksServices.ParksImplPort(); return park.byCountry(s); } }
@isTest global class ParkServiceMock implements WebServiceMock { global void doInvoke( Object stub, Object request, Map<String, Object> response, String endpoint, String soapAction, String requestName, String responseNS, String responseName, String responseType) { // start - specify the response you want to send parksServices.byCountryResponse response_x = new parksServices.byCountryResponse(); response_x.return_x = new List<String>{'Shiretoko National Park'}; // end response.put('response_x', response_x); } }
@isTest private class ParkLocatorTest { @isTest static void testCallout() { // This causes a fake response to be generated Test.setMock(WebServiceMock.class, new ParkServiceMock()); // Call the method that invokes a callout String s = 'japan'; String[] results = ParkLocator.getParks(s); System.assertEquals(results[0], 'Shiretoko National Park'); } }