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.

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.

Nota

Nota

Sempre que possível, use as mensagens de saída para cuidar das soluções de integração. Use callouts para serviços da Web de terceiros apenas quando for necessário.

No exemplo em questão, estamos usando uma 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.xml 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

  1. Em Configuração, insira Classes do Apex na caixa Busca rápida e clique em Classes do Apex.
  2. Clique em Gerar do WSDL.
  3. Clique em Escolher arquivo e selecione o arquivo calculator.xml que foi baixado.
  4. Clique em Analisar o WSDL. O aplicativo gerará um nome de classe padrão para cada namespace no documento WSDL e indicará qualquer erro.

    No exemplo em questão, 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.

  5. Clique em 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.

  1. Abra o Developer Console na engrenagem de configurações (Ícone de engrenagem de configuração).
  2. No Developer Console, selecione Debug (Depurar) | Open Execute Anonymous Window (Abrir janela Executar no modo anônimo).
  3. Exclua todo o código existente e insira o trecho a seguir.
    calculatorServices.CalculatorImplPort calculator = new  calculatorServices.CalculatorImplPort();
    Double x = 1.0;
    Double y = 2.0;
    Double result = calculator.doAdd(x,y);
    System.debug(result);
  4. Selecione Open Log (Abrir registro) e clique em Execute (Executar).
  5. 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 indicar 3.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 disso, mas 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.

  1. No Developer Console, selecione File (Arquivo) | New (Novo) | Apex Class (Classe do Apex).
  2. Para o nome da classe, insira AwesomeCalculator e clique em OK.
  3. 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);
        }
    }
  4. 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.

  5. No Developer Console, selecione File (Arquivo) | New (Novo) | Apex Class (Classe do Apex).
  6. Para o nome da classe, insira CalculatorCalloutMock e clique em OK.
  7. 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); 
       }
    }
  8. 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.

  9. No Developer Console, selecione File (Arquivo) | New (Novo) | Apex Class (Classe do Apex).
  10. Para o nome da classe, insira AwesomeCalculatorTest e clique em OK.
  11. 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
            System.assertEquals(3.0, result); 
        }
    }
  12. Pressione Ctrl+S para salvar.
  13. Para executar o teste, selecione Test (Teste) | Run All (Executar todos).

Agora, a classe AwesomeCalculator deverá estar exibindo 100% de cobertura de código!

Continue a aprender de graça!
Inscreva-se em uma conta para continuar.
O que você ganha com isso?
  • Receba recomendações personalizadas para suas metas de carreira
  • Pratique suas habilidades com desafios práticos e testes
  • Monitore e compartilhe seu progresso com os empregadores
  • Conecte-se a orientação e oportunidades de carreira