Llamadas Apex SOAP
Objetivos de aprendizaje
Tras completar este módulo, podrá:
- Generar clases de Apex con WSDL2Apex.
- Realizar una llamada para enviar datos a un servicio externo mediante SOAP.
- Probar llamadas mediante llamadas simuladas.
Siga el proceso con Trail Together
¿Desea seguir el proceso con un experto a medida que realiza este paso? Eche un vistazo a este video, parte de la serie Trail Together en Trailhead Live.
(Este video comienza en el minuto 45:49, en caso de que desee rebobinar y mirar el comienzo del paso nuevamente).
Usar WSDL2Apex para generar código Apex
Además de llamadas REST, Apex puede realizar llamadas a servicios web SOAP mediante XML. Trabajar con SOAP puede ser una experiencia difícil (pero necesaria). Afortunadamente, disponemos de herramientas para facilitar el proceso.
WSDL2Apex genera automáticamente clases de Apex a partir de un documento WSDL. Cuando descarga el archivo WSDL del servicio web y carga el WSDL, WSDL2Apex genera las clases de Apex correspondientes. Las clases de Apex crean el XML de SOAP, transmiten los datos y analizan el XML de respuesta en objetos de Apex. En lugar de desarrollar la lógica para crear y analizar el XML de los mensajes del servicio web, permita que las clases de Apex generadas por WSDL2Apex internamente controlen esta compleja estructura. Si está familiarizado con WSDL2Java o con la importación de WSDL como una referencia web en .NET, esta funcionalidad es similar a la de WSDL2Apex. No hay de qué.
En este ejemplo, vamos a usar un servicio web sencillo de calculadora para sumar dos números. Se trata de un servicio sumamente innovador. Lo primero que debemos hacer es descargar el archivo WSDL para generar las clases de Apex. Haga clic en este vínculo para descargar el archivo calculator.wsdl en la computadora. Recuerde la ubicación en la que guarda este archivo, ya que la necesitará en el siguiente paso.
Generar una clase de Apex a partir de WSDL
- En Setup (Configuración), ingrese
Apex Classes
(Clases de Apex) en el cuadro de búsqueda rápida y haga clic en Apex Classes (Clases de Apex).
- Haga clic en Generar desde WSDL.
- Haga clic en Seleccionar archivo y seleccione el archivo calculator.wsdl descargado.
- Haga clic en Parse WSDL (Analizar WSDL).
La aplicación genera un nombre de clase predeterminado para cada espacio de nombres en el documento WSDL e informa cualquier error.
En este ejemplo, use el nombre de clase predeterminado. No obstante, en la vida real, lo más recomendable es cambiar los nombres predeterminados para facilitar el trabajo con ellos y lograr que el código sea más intuitivo.
Llegó el momento de hablar abiertamente del analizador de WSDL. El análisis de WSDL2Apex es un proceso complejo conocido por su inestabilidad. El proceso de análisis puede generar un error por varios motivos, como un tipo no compatible, múltiples enlaces o elementos desconocidos. Lamentablemente, podría verse obligado a codificar manualmente las clases de Apex que llaman al servicio web o usan HTTP.
- Haga clic en Generate Apex code (Generar código de Apex).
En la página final del asistente, se muestran las clases generadas y los errores. La página también contiene un vínculo para ver el código generado correctamente.
Las clases de Apex generadas incluyen clases de tipo y código auxiliar para llamar al servicio web de terceros representado por el documento WSDL. Estas clases le permiten llamar al servicio web externo desde Apex. Para cada clase generada, se crea una segunda clase con el mismo nombre y el prefijo Async
. La clase calculatorServices
es para llamadas síncronas. La clase AsyncCalculatorServices
es para llamadas asíncronas.
Ejecutar la llamada
Requisitos
Para poder ejecutar este ejemplo, autorice la dirección URL de extremo de la llamada de servicio web, https://th-apex-soap-service.herokuapp.com, mediante los pasos que se indican en la sección Autorizar direcciones de extremo.
Ya puede ejecutar la llamada y comprobar si los dos números se suman correctamente. Tenga una calculadora a mano para comprobar los resultados.
- Abra Developer Console desde Configuración ().
- En Developer Console, seleccione Debug (Depurar) | Execute Anonymous Window (Abrir ventana de ejecución anónima).
- Elimine todo el código existente e inserte el siguiente miniprograma.Tenga en cuenta la implementación de calculatorServices con
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
. Las clases creadas con la opción Generate from WSDL (Generar desde WSDL) siempre tienen un método con el sufijoImplPort
.
- Seleccione Open Log (Abrir registro) y, a continuación, haga clic en Execute (Ejecutar).
- Una vez que se abra el registro, haga clic en Debug Only (Solo depurar) para ver la salida de las declaraciones
System.debug
. En el registro se debe mostrar3.0
.
Test Web Service Callouts
Todos los desarrolladores de Apex con experiencia saben que para implementar o empaquetar código Apex, dicho código debe tener una cobertura de prueba del 75 % como mínimo. Esta cobertura incluye las clases generadas por WSDL2Apex. Es posible que ya lo sepa, pero los métodos de prueba no admiten llamadas de servicio web, y las pruebas que realizan las llamadas de servicio web generan un error.
Por tanto, en este caso hay algún trabajo que hacer. Con el fin de evitar que las pruebas generen un error y aumentar la cobertura de código, Apex proporciona una interfaz WebServiceMock
integrada y el método Test.setMock
. Puede usar esta interfaz para recibir respuestas emuladas en un método de prueba, lo que proporciona la cobertura de prueba necesaria.
Especificar una respuesta simulada para llamadas
Si crea una clase de Apex a partir de WSDL, los métodos de la clase generada automáticamente llaman a WebServiceCallout.invoke
, que realiza la llamada al servicio externo. Cuando pruebe estos métodos, puede indicar al tiempo de ejecución de Apex que genere una respuesta emulada siempre que se llame a WebServiceCallout.invoke
. Para ello, implemente la interfaz WebServiceMock
y especifique una respuesta emulada para que el tiempo de ejecución de prueba la envíe.
Indique al tiempo de ejecución de Apex que envíe esta respuesta emulada mediante la llamada a Test.setMock
en el método de prueba. Para el primer argumento, pase WebServiceMock.class
. Para el segundo argumento, pase una nueva instancia de la implementación de interfaz WebServiceMock
.
Test.setMock(WebServiceMock.class, new MyWebServiceMockImpl());
Dado que este proceso es complejo, vamos a examinar algunas partes del código para ver un ejemplo completo. En este ejemplo, crea la clase que realiza la llamada (implementación simulada para pruebas) y la propia clase de prueba.
- En Developer Console, seleccione File (Archivo) | New (Nuevo) | Apex Class (Clase de Apex).
- Para el nombre de clase, ingrese
AwesomeCalculator
y, a continuación, haga clic en OK (Aceptar).
- Sustituya el código generado automáticamente por la siguiente definición de clase.
public class AwesomeCalculator { public static Double add(Double x, Double y) { calculatorServices.CalculatorImplPort calculator = new calculatorServices.CalculatorImplPort(); return calculator.doAdd(x,y); } }
- Presione CTRL+S para guardar.
Cree la implementación simulada para emular la llamada durante las pruebas. La implementación de WebServiceMock
llama al método doInvoke
, el cual devuelve la respuesta que ha especificado para las pruebas. La mayor parte de este código es reutilizable. La parte más compleja de este ejercicio es determinar cómo el servicio web debe devolver una respuesta para que pueda emular un valor.
- En Developer Console, seleccione File (Archivo) | New (Nuevo) | Apex Class (Clase de Apex).
- Para el nombre de clase, ingrese
CalculatorCalloutMock
y, a continuación, haga clic en OK (Aceptar).
- Sustituya el código generado automáticamente por la siguiente definición de clase.
@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); } }
- Presione CTRL+S para guardar.
Por último, el método de prueba debe indicar al tiempo de ejecución de Apex que envíe la respuesta emulada mediante la llamada a Test.setMock
antes de realizar la llamada en la clase AwesomeCalculator
. Al igual que ocurre con cualquier otro método de prueba, confirmamos la recepción del resultado correcto de la respuesta simulada.
- En Developer Console, seleccione File (Archivo) | New (Nuevo) | Apex Class (Clase de Apex).
- Para el nombre de clase, ingrese
AwesomeCalculatorTest
y, a continuación, haga clic en OK (Aceptar).
- Sustituya el código generado automáticamente por la siguiente definición de clase.
@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); } }
- Presione CTRL+S para guardar.
- Para ejecutar la prueba, seleccione Test (Prueba) | Run All (Ejecutar todo).
Ahora, la clase AwesomeCalculator
debe mostrar una cobertura de código del 100 %.
Recursos
- Guía del desarrollador de Apex: SOAP Services: Defining a Class from a WSDL Document
- Guía del desarrollador de Apex: Test Web Service Callouts
- Blog Salesforce Developers: Announcing the Open-Source WSDL2Apex Generator