Callouts SOAP do Apex
Objetivos de aprendizagem
Após concluir este módulo, você estará apto a:
- Gerar classes do Apex usando o WSDL2Apex.
- Fazer um callout para enviar dados a um serviço externo usando SOAP.
- Testar callouts usando callouts simulados.
Acompanhar com o Trail Together
Deseja acompanhar um especialista enquanto trabalha nesta etapa? Veja este vídeo que faz parte da série Trail Together no Trailhead Live.
(Este clipe começa na marca dos 45:49 minutos, caso você queira retroceder e ver o início da etapa novamente.)
Usar o WSDL2Apex para gerar o código do Apex
Além dos callouts REST, o Apex também pode fazer callouts para serviços da Web SOAP usando XML. Pode ser difícil (embora necessário) aprender a trabalhar com SOAP. Por sorte, contamos com ferramentas que facilitam o processo.
O WSDL2Apex gera automaticamente classes do Apex a partir de um documento WSDL. Basta baixar o arquivo WSDL de serviços da Web, fazer o carregamento do WSDL e esperar o WSDL2Apex gerar as classes do Apex para você. As classes do Apex compõem o XML SOAP, transmitem os dados e transformam o XML de resposta em objetos do Apex. Em vez de desenvolver a lógica para compor e transformar o XML das mensagens do serviço da Web, deixe que as classes do Apex geradas de forma interna pelo WSDL2Apex cuidem de todas essas tarefas. Se você costuma usar WSDL2Java ou importar um WSDL como uma referência da Web em .NET, essa funcionalidade é parecida com o WSDL2Apex. Não precisa agradecer.
No exemplo em questão, estamos usando um serviço simples de calculadora da Web para somar dois números. Um serviço inovador que está super na moda! A primeira coisa que precisamos fazer é baixar o arquivo WSDL para gerar as classes do Apex. Clique neste link e baixe o arquivo calculator.wsdl para seu computador. Preste atenção em onde esse arquivo está sendo armazenado, porque você precisará dele na próxima etapa.
Como gerar uma classe do Apex a partir do WSDL
- Em Setup (Configuração), insira
Apex Classes
(Classes do Apex) na caixa Quick Find (Busca rápida) e clique em Apex Classes (Classes do Apex).
- Clique em Gerar do WSDL.
- Clique em Escolher arquivo e selecione o arquivo calculator.wsdl que foi baixado.
- Clique em Parse WSDL (Analisar o WSDL).
O aplicativo gerará um nome de classe padrão para cada namespace no documento WSDL e indicará qualquer erro.
Neste exemplo, use o nome de classe padrão. Na vida real, contudo, é bastante recomendável alterar os nomes padrão para facilitar seu trabalho e tornar seu código mais intuitivo.
Chegou a hora de falar sinceramente sobre o analisador do WSDL. Todo mundo sabe que a análise do WSDL2Apex é um bicho de sete cabeças. O processo de análise pode dar errado por diversos motivos, como falta de suporte para o tipo, vinculações múltiplas ou elementos desconhecidos. Infelizmente, talvez você tenha que fazer a codificação manual das classes do Apex que chamam o serviço da Web ou usam HTTP.
- Clique em Generate Apex code (Gerar o código do Apex).
A última página do assistente mostra as classes que foram geradas e qualquer erro que tenha ocorrido. Essa página também fornece um link que mostra os códigos gerados corretamente.
As classes do Apex que forem geradas incluirão as classes stub e type usadas para chamar o serviço da Web de terceiros representado pelo documento WSDL. Essas classes possibilitam que você faça uma chamada do Apex para o serviço externo da Web. Para cada classe gerada, uma segunda classe é criada com o mesmo nome e o prefixo Async
. A classe calculatorServices
serve para callouts síncronos. A classe AsyncCalculatorServices
serve para callouts assíncronos.
Execução do callout
Pré-requisitos
Antes de executar o exemplo, autorize o URL do ponto de extremidade do callout do serviço da Web, https://th-apex-soap-service.herokuapp.com, seguindo os passos indicados na seção Autorizar endereços dos pontos de extremidade.
Agora, você poderá executar o callout e conferir se ele consegue somar dois números direito. Deixe uma calculadora por perto para verificar os resultados.
- Abra o Developer Console em Setup (Configurações) (
).
- No Developer Console, selecione Depurar | Abrir janela Executar no modo anônimo.
- Exclua todo o código existente e insira o trecho a seguir.Observe a implementação da classe calculatorServices com
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
. As classes criadas com Generate from WSDL (Gerar do WSDL) têm sempre um método com o sufixoImplPort
.
- Selecione Open Log (Abrir registro) e clique em Execute (Executar).
- Após a abertura do registro de depuração, clique em Debug Only (Apenas a depuração) para visualizar o resultado dos demonstrativos
System.debug
. O registro deve indicar3.0
.
Testar callouts de serviços da Web
Qualquer desenvolvedor experiente do Apex sabe que pelo menos 75% do código do Apex precisa ter cobertura de teste para fazer a implantação ou o empacotamento desse mesmo código. Essa cobertura inclui as nossas classes geradas pelo WSDL2Apex. Você já deve estar ciente de que os métodos de teste não dão suporte aos callouts de serviços da Web, e os testes que realizam callouts de serviços da Web dão errado.
Portanto, temos muito trabalho pela frente. Para evitar que os testes deem errado e para aumentar a cobertura de código, o Apex oferece uma interface WebServiceMock
integrada e o método Test.setMock
. É possível usar essa interface para receber respostas falsas em um método de teste, o que gera a cobertura de teste necessária.
Como especificar uma resposta simulada para os callouts
Ao criar uma classe do Apex a partir de um WSDL, os métodos da classe gerada automaticamente chamam WebServiceCallout.invoke
, que faz o callout para o serviço externo. Ao testar esses métodos, você pode orientar o tempo de execução do Apex a gerar uma resposta falsa toda vez que WebServiceCallout.invoke
for chamado. Para tanto, implemente a interface WebServiceMock
e especifique uma resposta falsa que será enviada pelo tempo de execução do teste.
Oriente o tempo de execução do Apex a enviar uma resposta falsa chamando o Test.setMock
no seu método de teste. Para o primeiro argumento, passe WebServiceMock.class
. Para o segundo argumento, passe uma nova instância da sua interface de implementação WebServiceMock
.
Test.setMock(WebServiceMock.class, new MyWebServiceMockImpl());
Entender isso não é moleza. Vejamos alguns códigos para ter um exemplo mais completo. No caso em questão, você criará a classe que faz o callout, uma implementação simulada de teste, e a própria classe de teste.
- No Developer Console, selecione File (Arquivo) | Novo (New) | Apex Class (Classe do Apex).
- Para o nome da classe, insira
AwesomeCalculator
e clique em OK.
- Substitua o código gerado automaticamente pela definição de classe a seguir.
public class AwesomeCalculator { public static Double add(Double x, Double y) { calculatorServices.CalculatorImplPort calculator = new calculatorServices.CalculatorImplPort(); return calculator.doAdd(x,y); } }
- Pressione Ctrl+S para salvar.
Crie sua implementação simulada para simular o callout durante o teste. Sua implementação de WebServiceMock
chama o método doInvoke
, que envia a resposta especificada para o teste. O maioria desse código é padronizada. A parte mais capciosa deste exercício é descobrir como o serviço da Web envia uma resposta para conseguir simular um valor.
- No Developer Console, selecione File (Arquivo) | Novo (New) | Apex Class (Classe do Apex).
- Para o nome da classe, insira
CalculatorCalloutMock
e clique em OK.
- Substitua o código gerado automaticamente pela seguinte definição de classe.
@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); } }
- Pressione Ctrl+S para salvar.
Por fim, seu método de teste precisa fazer o tempo de execução do Apex enviar a resposta falsa chamando o Test.setMock
antes de fazer o callout na classe AwesomeCalculator
. Assim como em qualquer outro método de teste, conferimos se recebemos o resultado correto da nossa resposta simulada.
- No Developer Console, selecione File (Arquivo) | Novo (New) | Apex Class (Classe do Apex).
- Para o nome da classe, insira
AwesomeCalculatorTest
e clique em OK.
- Substitua o código gerado automaticamente pela seguinte definição de classe.
@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); } }
- Pressione Ctrl+S para salvar.
- Para executar o teste, selecione Teste | Executar todos.
Agora, a classe AwesomeCalculator
deverá estar exibindo 100% de cobertura de código!
Recursos
-
Guia do desenvolvedor do Apex: Serviços SOAP: Como definir uma classe com um documento WSDL
-
Guia do desenvolvedor do Apex: Testar callouts de serviços da Web
-
Salesforce Developers Blog: Apresentamos o Gerador WSDL2Apex de código aberto