Apex SOAP コールアウト
学習の目的
このモジュールを完了すると、次のことができるようになります。
- WSDL2Apex を使用して Apex クラスを生成する。
- SOAP を使用してコールアウトを実行し、データを外部サービスに送信する。
- 疑似コールアウトを使用して、コールアウトをテストする。
一緒にトレイルを進みましょう
エキスパートの説明を見ながらこのステップを実行したい場合は、次の動画をご覧ください。これは Trailhead Live の「Trail Together」(一緒にトレイル) シリーズの一部です。
(この動画は 45:49 の時点から始まります。戻して手順の最初から見直す場合はご注意ください。)
WSDL2Apex を使用した Apex コードの生成
REST コールアウトの他に、Apex は XML を使用して SOAP Web サービスへのコールアウトを実行することもできます。SOAP での作業は、必要ですが手間がかかる場合があります。幸いにも、このプロセスを簡単にするツールがあります。
WSDL2Apex は、WSDL ドキュメントから Apex クラスを自動的に生成します。Web サービスの WSDL ファイルをダウンロードして WSDL をアップロードすると、WSDL2Apex によって Apex クラスが生成されます。Apex クラスは、SOAP XML を構築してデータを転送し、応答 XML を Apex オブジェクトで解析します。Web サービスメッセージの XML を構築および解析するロジックを開発する代わりに、WSDL2Apex で生成された Apex クラスでそのオーバーヘッドをすべて内部的に処理します。WSDL2Java や、.NET の Web 参照として WSDL をインポートすることに精通している場合、この機能は WSDL2Apex に似ていると感じるでしょう。どうぞお試しください。
この例では、簡易な電卓の Web サービスを使用して、2 つの数字を加算します。これは、大流行している画期的なサービスです。まず、WSDL ファイルをダウンロードして Apex クラスを生成する必要があります。このリンクをクリックして、calculator.wsdl ファイルをコンピューターに保存します。次のステップで必要になるため、このファイルを保存した場所を忘れないでください。
WSDL からの Apex クラスの生成
- [Setup (設定)] から、[Quick Find (クイック検索)] ボックスに
Apex Classes
(Apex クラス) と入力し、[Apex Classes (Apex クラス)] をクリックします。
-
[WSDL からの生成] をクリックします。
-
[ファイルを選択] をクリックし、ダウンロードした calculator.wsdl ファイルを選択します。
-
[Parse WSDL (WSDL を解析)] をクリックします。
アプリケーションが、WSDL ドキュメント内の各名前空間のデフォルトクラス名を生成し、エラーがあれば報告します。
この例では、このデフォルトクラス名を使用します。ただし、実際には作業しやすく、直感的なコードになるようにデフォルト名を変更することを強くお勧めします。
WSDL パーサーについて正直にお話しするときがきました。WSDL2Apex の解析は、扱いづらいことで有名です。解析プロセスは、さまざまな理由 (サポートされていないタイプ、複数のバインド、または不明な要素など) で失敗することがあります。残念ながら、Web サービスをコールする、または HTTP を使用する Apex クラスを手動でコーディングすることが必要になる可能性があります。
-
[Generate Apex code (Apex コードの生成)] をクリックします。
ウィザードの最終ページに、生成されたクラスとエラーが表示されます。また、正常に生成されたコードを表示するためのリンクも示されます。
生成された Apex クラスには、WSDL ドキュメントで示されるサードパーティ Web サービスをコールするスタブと種別クラスが含まれています。これらのクラスにより、Apex から外部の Web サービスをコールすることができます。生成されたクラスごとに、同じ名前で Async
というプレフィックスが付いた 2 つ目のクラスが作成されます。calculatorServices
クラスは、同期コールアウトに使用されます。AsyncCalculatorServices
クラスは、非同期コールアウトに使用されます。
コールアウトの実行
前提条件
この例を実行する前に、「エンドポイントアドレスの承認」セクションの手順を使用して、Web サービスコールアウトのエンドポイント URL (https://th-apex-soap-service.herokuapp.com) を承認してください。
これで、コールアウトを実行して、2 つの数字が正しく加算されたかどうかを確認できます。電卓を手元に置いて結果を確認しましょう。
- [Setup (設定)] () から [Developer Console (開発者コンソール)] を開きます。
- 開発者コンソールで、[Debug (デバッグ)] | [Open Execute Anonymous Window (実行匿名ウィンドウを開く)] を選択します。
- 既存のコードをすべて削除し、次のスニペットを挿入します。calculatorServices の実装に
calculatorServices.CalculatorImplPort calculator = new calculatorServices.CalculatorImplPort(); Double x = 1.0; Double y = 2.0; Double result = calculator.doAdd(x,y); System.debug(result);
calculatorServices.CalculatorImplPort
が使用されています。[Generate from WSDL (WSDL からの生成)] で作成されたクラスには常にImplPort
サフィックスの付いたメソッドがあります。
-
[Open Log (ログを開く)] を選択し、[Execute (実行)] をクリックします。
- デバッグログが開いたら、[Debug Only (デバッグのみ)] をクリックし、
System.debug
ステートメントの出力を表示します。ログには3.0
と表示されます。
Web サービスコールアウトのテスト
経験豊富な Apex 開発者は皆、Apex コードをリリースまたはパッケージ化するには、そのコードのテストカバー率が少なくとも 75% に達している必要があることを知っています。このカバー率には、WSDL2Apex で生成されたクラスも含まれます。以前に聞いたことがあるかもしれませんが、テストメソッドは Web サービスコールアウトをサポートせず、Web サービスコールアウトを実行するテストは失敗します。
そのため、少し作業が必要になります。テストの失敗を回避し、コードカバー率を高めるために、Apex には組み込みの WebServiceMock
インターフェースと Test.setMock
メソッドが用意されています。このインターフェースを使用して、テストメソッドで疑似応答を受信できるため、必要なテストカバー率を達成できます。
コールアウトの疑似応答の指定
WSDL から Apex クラスを作成した場合、自動生成されたクラスのメソッドが WebServiceCallout.invoke
をコールし、そこから外部サービスへのコールアウトが実行されます。これらのメソッドをテストする場合、WebServiceCallout.invoke
がコールされたときには常に疑似応答を生成するように Apex ランタイムに指示できます。そのためには、WebServiceMock
インターフェースを実装し、送信するテストランタイムの疑似応答を指定します。
テストメソッドで Test.setMock
をコールしてこの疑似応答を送信するように Apex ランタイムに指示します。第 1 引数で、WebServiceMock.class
を渡します。第 2 引数では、WebServiceMock
インターフェース実装の新しいインスタンスを渡します。
Test.setMock(WebServiceMock.class, new MyWebServiceMockImpl());
学習する内容がたくさんあるので、まずは完全な例のいくつかのコードを見ていきましょう。この例では、コールアウト、テスト用の疑似実装、およびテストクラス自体を実行するクラスを作成します。
- 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] を選択します。
- クラス名に
AwesomeCalculator
と入力し、[OK] をクリックします。
- 自動生成されるコードを次のクラス定義で置き換えます。
public class AwesomeCalculator { public static Double add(Double x, Double y) { calculatorServices.CalculatorImplPort calculator = new calculatorServices.CalculatorImplPort(); return calculator.doAdd(x,y); } }
-
CTRL+S キーを押して保存します。
疑似実装を作成して、テスト中に疑似コールアウトを実行します。WebServiceMock
の実装では doInvoke
メソッドがコールされ、テスト用に指定した応答が返されます。このコードの大部分は定型です。この演習の最も難しい部分は、Web サービスからどのように応答が返されるのかを理解して、疑似値を使用できるようにすることです。
- 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] を選択します。
- クラス名に
CalculatorCalloutMock
と入力し、[OK] をクリックします。
- 自動生成されるコードを次のクラス定義で置き換えます。
@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); } }
-
CTRL+S キーを押して保存します。
最後に、テストメソッドは、AwesomeCalculator
クラスでコールアウトを実行する前に Test.setMock
をコールして疑似応答を送信するように Apex ランタイムに指示する必要があります。疑似応答でも、他のテストメソッドと同様に正しい結果を受信できます。
- 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] を選択します。
- クラス名に
AwesomeCalculatorTest
と入力し、[OK] をクリックします。
- 自動生成されるコードを次のクラス定義で置き換えます。
@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 Assert.areEqual(3.0, result); } }
-
CTRL+S キーを押して保存します。
- テストを実行するには、[Test (テスト)] | [Run All (すべて実行)] を選択します。
これで、AwesomeCalculator
クラスに表示されるコードカバー率が 100% になります。
リソース
- Apex 開発者ガイド: SOAP サービス: WSDL ドキュメントからのクラスの定義
- Apex 開発者ガイド: Web サービスコールアウトのテスト
- Salesforce 開発者ブログ: Announcing the Open-Source WSDL2Apex Generator (オープンソース WSDL2Apex ジェネレーターの発表)