Apex-SOAP-Callouts
Lernziele
Nachdem Sie dieses Modul abgeschlossen haben, sind Sie in der Lage, die folgenden Aufgaben auszuführen:
- Generieren von Apex-Klassen mithilfe von WSDL2Apex
- Ausführen eines Callouts zum Senden von Daten an einen externen Dienst mithilfe von SOAP
- Testen von Callouts mithilfe simulierter Callouts
Mit Trail Together einem Dozenten folgen
Möchten Sie bei diesem Schritt einem Experten folgen? Schauen Sie sich dieses Video an, das Teil der Reihe "Trail Together" auf Trailhead Live ist.
(Dieser Clip beginnt bei Minute 45:49, für den Fall, dass Sie zurückspringen und den Anfang des Schritts noch einmal sehen möchten.)
Generieren von Apex-Code mit WSDL2Apex
Neben REST-Callouts kann Apex mithilfe von XML auch Callouts an SOAP-Webservices richten. Das Arbeiten mit SOAP kann eine unangenehme (aber notwendige) Erfahrung sein. Zum Glück haben wir Tools, die den Prozess erleichtern.
WSDL2Apex generiert Apex-Klassen automatisch aus einem WSDL-Dokument. Sie laden die WSDL-Datei des Webservices herunter, laden dann die WSDL-Datei hoch, woraufhin WSDL2Apex die Apex-Klassen für Sie erstellt. Die Apex-Klassen konstruieren die SOAP XML, übertragen die Daten und analysieren die Antwort-XML in Apex-Objekte. Anstatt die Logik zum Konstruieren und Analysieren der XML der Webservicenachrichten zu entwickeln, lassen Sie die von WSDL2Apex generierten Apex-Klassen all diesen Verarbeitungsaufwand intern übernehmen. Wenn Sie mit WSDL2Java oder dem Importieren einer WSDL-Datei als Webverweis in .NET vertraut sind, ist diese Funktionalität mit WSDL2Apex vergleichbar. Bitte schön!
Bei diesem Beispiel verwenden wir einen einfachen Webservice mit einem Rechner zum Addieren zweier Zahlen. Dieser bahnbrechende Service ist der letzte Schrei! Zunächst müssen wir die WSDL-Datei herunterladen, um die Apex-Klassen zu generieren. Klicken Sie auf diesen Link und laden Sie die Datei "calculator.wsdl" auf Ihren Computer herunter. Merken Sie sich den Speicherort der Datei, da Sie sie im nächsten Schritt benötigen.
Erstellen einer Apex-Klasse aus der WSDL
- Geben Sie unter "Setup" im Feld "Quick Find (Schnellsuche)" den Text
Apex Classes
(Apex-Klassen) ein und klicken Sie dann auf Apex Classes (Apex-Klassen).
- Klicken Sie auf Aus WSDL generieren.
- Klicken Sie auf Datei auswählen und wählen Sie die heruntergeladene Datei calculator.wsdl aus.
- Klicken Sie auf WSDL analysieren.
Die Anwendung generiert einen Standardklassennamen für die einzelnen Namespaces im WSDL-Dokument und meldet etwaige Fehler.
In diesem Beispiel wird der Standardklassennamen verwendet. Doch in der Praxis wird ausdrücklich empfohlen, die Standardnamen zu ändern, um das Arbeiten mit ihnen zu erleichtern und Ihren Code intuitiver zu gestalten.
Doch lassen Sie uns zunächst ehrlich über den WSDL-Parser sprechen. Die WSDL2Apex-Analyse ist notorisch unbeständig. Der Analyseprozess kann aus mehreren Gründen fehlschlagen, z. B. aufgrund eines nicht unterstützten Typs, mehrerer Bindungen oder unbekannter Elemente. Leider könnten Sie gezwungen sein, die Apex-Klassen manuell zu programmieren, die den Webservice aufrufen oder HTTP verwenden.
- Klicken Sie auf Apex-Code generieren.
Auf der letzten Seite des Assistenten werden die generierten Klassen sowie etwaige Fehler angezeigt. Die Seite enthält darüber hinaus einen Link zum Anzeigen des erfolgreich erstellten Codes.
Die generierten Apex-Klassen enthalten Stub- und Typenklassen zum Aufrufen des Drittanbieter-Webservice, für den das WSDL-Dokument steht. Diese Klassen ermöglichen den Aufruf des externen Webservice aus Apex. Für jede generierte Klasse wird eine zweite Klasse mit demselben Namen und mit dem Präfix Async
erstellt. Die Klasse calculatorServices
ist für synchrone Callouts. Die Klasse AsyncCalculatorServices
ist für asynchrone Callouts.
Ausführen des Callouts
Voraussetzungen
Ehe Sie dieses Beispiel ausführen, müssen Sie den Endpunkt-URL des Webservice-Callouts, https://th-apex-soap-service.herokuapp.com anhand der Schritte im Abschnitt Autorisieren von Endpunktadressen autorisieren.
Nun können Sie den Callout ausführen und prüfen, ob die beiden Zahlen ordnungsgemäß addiert werden. Halten Sie einen Rechner bereit, um die Ergebnisse zu prüfen.
- Klicken Sie auf das Setup-Zahnradsymbol () und wählen Sie "Developer Console (Entwicklerkonsole)" aus.
- Klicken Sie in der Entwicklerkonsole auf Debug | Open Execute Anonymous Window.
- Löschen Sie den gesamten vorhandenen Code und fügen Sie den folgenden Codeabschnitt ein. Beachten Sie die Implementierung von calculatorServices mit
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
. Die mit der Funktion Generate from WSDL (Aus WSDL generieren) erstellten Klassen weisen stets eine Methode mit dem SuffixImplPort
auf.
- Wählen Sie Open Log aus und klicken Sie auf Execute.
- Klicken Sie nach Öffnen des Debug-Protokolls auf Debug Only, um die Ausgabe der
System.debug
-Anweisungen anzuzeigen. Das Protokoll sollte3.0
anzeigen.
Test Web Service Callouts
Als erfahrene Apex-Entwickler wissen Sie, dass zum Bereitstellen oder Packen von Apex-Code mindestens 75 % dieses Codes von Tests abgedeckt sein müssen. Diese Abdeckung schließt unsere von WSDL2Apex erstellten Klassen ein. Sie haben vielleicht schon zuvor davon gehört, dass Testmethoden keine Webservice-Callouts unterstützen, sodass Tests, die Webservice-Callouts durchführen, fehlschlagen.
Es ist also etwas Arbeit erforderlich. Zum Verhindern des Fehlschlagens von Tests und Steigern der Codeabdeckung bietet Apex die integrierte WebServiceMock
-Schnittstelle und die Test.setMock
-Methode. Sie können mithilfe dieser Schnittstelle in einem Test simulierte Antworten empfangen und so für die erforderliche Testabdeckung sorgen.
Angeben einer simulierten Antwort für Callouts
Wenn Sie eine Apex-Klasse aus einer WSDL-Datei erstellen, rufen die Methoden in der automatisch generierten Klasse WebServiceCallout.invoke
auf, wodurch der Callout an den externen Service erfolgt. Beim Testen dieser Methoden können Sie die Apex-Laufzeit anweisen, eine simulierte Antwort zu generieren, wenn WebServiceCallout.invoke
aufgerufen wird. Implementieren Sie hierzu die WebServiceMock
-Schnittstelle und geben Sie eine simulierte Antwort an, die von der testenden Laufzeit gesendet werden soll.
Weisen Sie die Apex-Laufzeit an, diese simulierte Antwort zu senden, indem in Ihrer Testmethode Test.setMock
aufgerufen wird. Übergeben Sie für das erste Argument WebServiceMock.class
. Übergeben Sie für das zweite Argument eine neue Instanz Ihrer WebServiceMock
-Schnittstellenimplementierung.
Test.setMock(WebServiceMock.class, new MyWebServiceMockImpl());
Da gibt es viel zu begreifen, weshalb wir uns den Code eines vollständigen Beispiels ansehen möchten. Bei diesem Beispiel erstellen Sie die Klasse, die den Callout ausführt, eine simulierte Implementierung für Tests und die Testklasse selbst.
- Klicken Sie in der Developer Console auf File (Datei) | New (Neu) | Apex Class (Apex-Klasse).
- Geben Sie als Klassennamen
AwesomeCalculator
ein und klicken Sie auf OK.
- Ersetzen Sie automatisch generierten Code durch die folgende Klassendefinition.
public class AwesomeCalculator { public static Double add(Double x, Double y) { calculatorServices.CalculatorImplPort calculator = new calculatorServices.CalculatorImplPort(); return calculator.doAdd(x,y); } }
- Drücken Sie STRG+S, um zu speichern.
Erstellen Sie Ihre simulierte Implementierung, um den Callout während der Tests zu simulieren. Ihre Implementierung von WebServiceMock
ruft die doInvoke
-Methode auf, die die Antwort zurückgibt, die Sie für Tests angeben. Der Großteil dieses Codes besteht aus Bausteinen. Der schwierigste Teil dieser Übung ist das Herausfinden, wie der Webservice eine Antwort zurückgibt, damit Sie einen Wert simulieren können.
- Klicken Sie in der Developer Console auf File (Datei) | New (Neu) | Apex Class (Apex-Klasse).
- Geben Sie als Klassennamen
CalculatorCalloutMock
ein und klicken Sie auf OK.
- Ersetzen Sie den automatisch generierten Code durch die folgende Klassendefinition.
@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); } }
- Drücken Sie STRG+S, um zu speichern.
Schließlich muss Ihre Testmethode die Apex-Laufzeit anweisen, die simulierte Antwort zu senden, indem Test.setMock
aufgerufen wird, bevor der Callout an die AwesomeCalculator
-Klasse erfolgt. Wie bei anderen Testmethoden bestätigen wir, dass das richtige Ergebnis aus unserer simulierten Antwort empfangen wurde.
- Klicken Sie in der Developer Console auf File (Datei) | New (Neu) | Apex Class (Apex-Klasse).
- Geben Sie als Klassennamen
AwesomeCalculatorTest
ein und klicken Sie auf OK.
- Ersetzen Sie den automatisch generierten Code durch die folgende Klassendefinition.
@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); } }
- Drücken Sie STRG+S, um zu speichern.
- Um diesen Test auszuführen, klicken Sie auf Test | Run All.
Für die AwesomeCalculator
-Klasse sollte nun eine Codeabdeckung von 100 % angezeigt werden!
Ressourcen
- Apex Developer Guide: SOAP Services: Defining a Class from a WSDL Document
- Apex Developer Guide: Test Web Service Callouts
- Salesforce Developers-Blog: Announcing the Open-Source WSDL2Apex Generator