Apex SOAP コールアウト

学習の目的

このモジュールを完了すると、次のことができるようになります。
  • WSDL2Apex を使用して Apex クラスを生成する。
  • SOAP を使用してコールアウトを実行し、データを外部サービスに送信する。
  • 疑似コールアウトを使用して、コールアウトをテストする。

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 サービスのコールアウトを使用します。

この例では、簡易な電卓の Web サービスを使用して、2 つの数字を加算します。これは、大流行している画期的なサービスです。まず、WSDL ファイルをダウンロードして Apex クラスを生成する必要があります。このリンクをクリックして、calculator.xml ファイルをコンピュータに保存します。次のステップで必要になるため、このファイルを保存した場所を忘れないでください。

WSDL からの Apex クラスの生成

  1. [設定] から、[クイック検索] ボックスに「Apex クラス」と入力し、[Apex クラス] をクリックします。
  2. [WSDL からの生成] をクリックします。
  3. [ファイルを選択] をクリックし、ダウンロードした calculator.xml ファイルを選択します。
  4. [WSDL を解析] をクリックします。アプリケーションが、WSDL ドキュメント内の各名前空間のデフォルトクラス名を生成し、エラーがあれば報告します。

    この例では、このデフォルトクラス名を使用します。ただし、実際には作業しやすく、直感的なコードになるようにデフォルト名を変更することを強くお勧めします。

    WSDL パーサーについて正直にお話するときがきました。WSDL2Apex の解析は、扱いづらいことで有名です。解析プロセスは、さまざまな理由 (サポートされていないタイプ、複数のバインド、または不明な要素など) で失敗することがあります。残念ながら、Web サービスをコールする、または HTTP を使用する Apex クラスを手動でコーディングすることが必要になる可能性があります。

  5. [Apex コードの生成] をクリックします。ウィザードの最終ページに、生成されたクラスとエラーが表示されます。また、正常に生成されたコードを表示するためのリンクも示されます。

生成された Apex クラスには、WSDL ドキュメントで示されるサードパーティ Web サービスをコールするスタブと種別クラスが含まれています。これらのクラスにより、Apex から外部の Web サービスをコールすることができます。生成されたクラスごとに、同じ名前で Async というプレフィックスが付いた 2 つ目のクラスが作成されます。calculatorServices クラスは、同期コールアウトに使用されます。AsyncCalculatorServices クラスは、非同期コールアウトに使用されます。

コールアウトの実行

前提条件

この例を実行する前に、「エンドポイントアドレスの承認」セクションの手順を使用して、Web サービスコールアウトのエンドポイント URL (https://th-apex-soap-service.herokuapp.com) を承認してください。

これで、コールアウトを実行して、2 つの数字が正しく加算されたかどうかを確認できます。電卓を手元に置いて結果を確認しましょう。

  1. 設定ギア (設定ギアアイコン) から開発者コンソールを開きます。
  2. 開発者コンソールで、[Debug (デバッグ)] | [Open Execute Anonymous Window (実行匿名ウィンドウを開く)] を選択します。
  3. 既存のコードをすべて削除し、次のスニペットを挿入します。
    calculatorServices.CalculatorImplPort calculator = new  calculatorServices.CalculatorImplPort();
    Double x = 1.0;
    Double y = 2.0;
    Double result = calculator.doAdd(x,y);
    System.debug(result);
  4. [Open Log (ログを開く)] を選択し、[Execute (実行)] をクリックします。
  5. デバッグログが開いたら、[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());

学習する内容がたくさんあるので、まずは完全な例のいくつかのコードを見ていきましょう。この例では、コールアウト、テスト用の疑似実装、およびテストクラス自体を実行するクラスを作成します。

  1. 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] を選択します。
  2. クラス名として「AwesomeCalculator」と入力し、[OK] をクリックします。
  3. 自動生成されるコードを次のクラス定義で置き換えます。
    public class AwesomeCalculator {
        public static Double add(Double x, Double y) {
            calculatorServices.CalculatorImplPort calculator = 
                new calculatorServices.CalculatorImplPort();
            return calculator.doAdd(x,y);
        }
    }
  4. CTRL+S キーを押して保存します。

    疑似実装を作成して、テスト中に疑似コールアウトを実行します。WebServiceMock の実装では doInvoke メソッドがコールされ、テスト用に指定した応答が返されます。このコードの大部分は定型です。この演習の最も難しい部分は、Web サービスからどのように応答が返されるのかを理解して、疑似値を使用できるようにすることです。

  5. 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] を選択します。
  6. クラス名として「CalculatorCalloutMock」と入力し、[OK] をクリックします。
  7. 自動生成されるコードを次のクラス定義で置き換えます。
    @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); 
       }
    }
  8. CTRL+S キーを押して保存します。

    最後に、テストメソッドは、AwesomeCalculator クラスでコールアウトを実行する前に Test.setMock をコールして疑似応答を送信するように Apex ランタイムに指示する必要があります。疑似応答でも、他のテストメソッドと同様に正しい結果を受信できます。

  9. 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] を選択します。
  10. クラス名として「AwesomeCalculatorTest」と入力し、[OK] をクリックします。
  11. 自動生成されるコードを次のクラス定義で置き換えます。
    @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); 
        }
    }
  12. CTRL+S キーを押して保存します。
  13. テストを実行するには、[Test (テスト)] | [Run All (すべて実行)] を選択します。

これで、AwesomeCalculator クラスに表示されるコードカバー率が 100% になります。