tyoshikawa1106のブログ

- Force.com Developer Blog -

SFDC:ApexとSOAP Callouts

Trailheadに紹介されていたApexとSOAP Calloutsについてです。

f:id:tyoshikawa1106:20160117162713p:plain

Apex SOAP Callouts Unit | Salesforce Trailhead


まず、下記リンク先からXMLファイルをダウンロードします。

https://th-apex-soap-service.herokuapp.com/assets/calculator.xml

f:id:tyoshikawa1106:20160117162822p:plain


Apexクラスページの「Generate from WSDL」ボタンをクリックします。
f:id:tyoshikawa1106:20160117163010p:plain


先ほどダウンロードしたXMLファイルをアップします。
f:id:tyoshikawa1106:20160117163151p:plain


これでXMLファイルからApexクラスを生成できます。
f:id:tyoshikawa1106:20160117163213p:plain


f:id:tyoshikawa1106:20160117163302p:plain


f:id:tyoshikawa1106:20160117163323p:plain


f:id:tyoshikawa1106:20160117163336p:plain


生成された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); 
    }
}


ざっくりですがこんな感じです。

追記

別のパターンも記載しておきます。国名を渡すと公園名が取得できる処理の場合です。

https://th-apex-soap-service.herokuapp.com/assets/parks.xml

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');
    }
}