Na minha carreira passada, muitas vezes descobri que algumas pessoas não escreveram código de teste, e a razão pela qual alegaram não escrever era que elas não podiam escrever facilmente casos de teste, cobrindo vários módulos diferentes. Bem, acredito que a maioria deles não tem alguns meios técnicos mais fáceis de mestrar ou não tem tempo para descobrir. Afinal, sempre haverá várias pressões, como o progresso no trabalho. Como não sei como testar, muitas vezes ignoro os testes de integração, e os problemas provocados estão obtendo um software pior, mais e mais clientes e clientes mais decepcionados. Então, quero compartilhar algumas experiências pessoais para revelar o mistério dos testes de integração.
Como integrar melhor os testes de projetos baseados em primavera <BR /> Usando ferramentas: Spring, Junit, Mockito
Imagine que existe um projeto de primavera que integra alguns serviços externos, como alguns serviços da Web bancários. Em seguida, os problemas encontrados ao escrever casos de teste para este projeto e a conclusão desses testes em um sistema de integração contínua são basicamente os mesmos:
1. Haverá transações em cada teste e cada transação requer um custo monetário, que será suportado pelo cliente;
2. Os pedidos excessivos emitidos durante o teste podem ser considerados solicitações maliciosas, o que pode fazer com que a conta no banco seja bloqueada, com a conseqüência da falha do teste;
3. Quando o teste é realizado usando um ambiente de não produção, os resultados do teste não são muito confiáveis. Da mesma forma, a conseqüência é que o teste falha.
Geralmente, quando você testa uma única classe, o problema é fácil de resolver, porque você pode virtualizar alguns serviços externos para chamada. Mas, ao testar todo o enorme processo de negócios, significa que você precisa testar vários componentes e, neste momento, você precisa incorporar esses componentes no contêiner de mola para gerenciamento. Felizmente, a Spring inclui uma excelente estrutura de teste que permite injetar grãos de arquivos de configuração do ambiente de produção no ambiente de teste, mas para os chamados serviços externos, precisamos escrever implementações simuladas. A primeira reação das pessoas comuns pode ser reinjetar (modificar) os grãos injetados pela primavera durante o estágio de configuração do teste, mas esse método precisa ser cuidadosamente considerado.
AVISO: Dessa maneira, seu código de teste quebra o próprio comportamento do contêiner; portanto, não há garantia de que ele será o mesmo que os resultados do seu teste em um ambiente real.
De fato, em vez de implementar a classe simulada primeiro e depois reinventá -la no feijão necessário, podemos deixar a primavera nos ajudar a injetar a classe simulada desde o início. Vamos demonstrá -lo com código.
O projeto de amostra contém uma classe chamada BankService, representando a chamada para o serviço externo, e uma classe chamada UserBalakerService, que chama BankService. O UserBalancyService é implementado muito simples, apenas para concluir a conversão de equilíbrio de string em tipo duplo.
Código fonte do BankService.java:
Public Interface BankService {String getBalanceByEmail (string email);} Código fonte do BankServiceImpl.java:
public class BankServiceImpl implementa o BankService {@Override public String getBalanceByEmail (string email) {lança novo UnsupportEdOperationException ("Operação falhou devido à exceção externa"); }} Código -fonte do userBalanceservice.java:
Interface UserBalances Service {Double GetAccoundBalance (String email);} Código -fonte do UserBalanceserviceImpl.java:
classe pública UserBalanceserviceImpl implementa o userBalances Service {@AUTOWIRED PRIVADO BANKSERVICE BANKSERVICE; @Override public Double GetAccountBalance (string email) {return duplo.valueof (BankService.getBalanceByEmail (email)); }} Depois, há o arquivo de configuração XML da Spring, adicionando a declaração de feijão necessária.
Código fonte do ApplicationContext.xml:
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id = "BankService"/> <ré-thean/sdean/spring-beans.xsd "> <Bean id =" BankSerice "/> <réangues)
Aqui está o código -fonte da classe de teste UserBalanceserviceImpltest.java:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (Locations = "ClassPath: /springtest/springockito/ApplicationContext.xml") Public class UserBalancesViceImplProfilEtest @AUTOUNDIDEDIDODEDIDADO PIVERTIVERSERVERVEDERVERVERVICE; @Autowired Private BankService BankService; @Test public void deve -renunciarmockedBalance () {duplo balance = userBalanceservice.getAccountBalance ("[email protected]"); assertequals (Balance, Double.ValueOf (123.45d)); }} Como esperávamos, o método de teste relata uma exceção não suportada de exceção. Nosso objetivo atual é substituir o BankService pela nossa implementação de simulação. Não há problema em usar o Mockito diretamente para gerar feijões de fábrica, mas há uma opção melhor, use a estrutura Springockito. Você pode ter uma ideia aproximada antes de continuar.
A pergunta restante é simples: como injetar a mola em um feijão simulado em vez de um feijão real, não havia outro caminho antes da primavera 3.1, exceto para criar um novo arquivo de configuração XML. Mas como a primavera introduziu a definição de perfil de feijão, temos uma solução mais elegante, embora essa abordagem também exija um arquivo de configuração XML adicional especificamente para teste. Aqui está o código para o arquivo de configuração testApplicationContext.xml usado para testar:
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 xmlns:mockito="http://www.mockito.org/spring/mockito" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tipspipockito/src/main/resources/spring/mockito.xsd "> Resource = "ClassPath: /springtest/springockito/applicationContext.xml"/> <Feans Profile = "Springtest"> <Mockito: Mock Id = "BankService"/> </ Beans> </ Beans>
O código -fonte da classe de teste UserBalances ServiceImplProfileTest.java depois de fazer modificações correspondentes:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (locations = "ClassPath: /springtest/springockito/testapplicationContext.xml")@ActiveProfiles (perfis = {"Springtest"}) Public ClassEserveReviceMPROFILES ({"Springtest"}) @Autowired Private BankService BankService; @Before public void setUp () lança a Exceção {Mockito.when (BankService.getBalanceByEmail ("[email protected]")). Thenreturn (string.valueof (123.45d)); } @Test public void deve -renunciarmockedBalance () {duplo balance = userBalanceservice.getAccountBalance ("[email protected]"); assertequals (Balance, Double.ValueOf (123.45d)); }} Você deve ter notado que, no método de configuração, definimos o comportamento simulado e adicionamos a anotação @profile à classe. Esta anotação ativa um perfil chamado Springtest, para que o feijão simulado usando Springockito possa ser injetado automaticamente em qualquer lugar necessário. O resultado da execução deste teste será bem -sucedido porque a mola injeta a versão simulada por Springockito, não a versão declarada no ApplicationContext.xml.
Continue a otimizar nossos testes
Se pudermos levar ainda mais a solução para esse problema, este artigo não parecerá falho. Springockito oferece outro nome chamado
Springockito Anotation Framework, que nos permite usar anotações nas classes de teste para injetar classes simuladas. Antes de continuar lendo, é melhor ir ao site para dar uma olhada. Ok, aqui está o código de teste modificado.
Source code of UserBalanceServiceImplAnnotationTest.java: @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:/springtest/springockito/applicationContext.xml")public class UserBalanceServiceImplAnnotationTest { @AUTOWIRED PRIVADO PERSIVERSERVERVICE UserBalaService; @Autowired @replacewithmock Private BankService BankService; @Before public void Setup () lança a Exceção {Mockito.when (BankService.getBalanceByEmail ("[email protected]")). Thenreturn (string.valueof (valueof (123.45d))); } @Test public void deve -renunciarmockedBalance () {duplo balance = userBalanceservice.getAccountBalance ("[email protected]"); assertequals (Balance, Valueof (123.45d)); }} Observe que não há arquivo de configuração XML recentemente apresentado aqui, mas o ApplicationContext.xml do ambiente formal é usado diretamente. Utilizamos a anotação @replacewithmock para marcar o feijão do tipo BankService e, em seguida, definimos o comportamento da classe simulada no método de configuração.
PostScript
O projeto Springockito-Anotações tem uma enorme vantagem, ou seja, cria nosso código de teste sobre cobertura de dependência, para que não precisemos definir arquivos de configuração XML adicionais ou modificar os arquivos de configuração do ambiente de produção para teste. Se o Springockito-anlações não for usado, não temos escolha a não ser definir arquivos de configuração XML adicionais. Portanto, recomendo fortemente que você use o Springockito-anotações em seus testes de integração para que você possa minimizar o impacto dos casos de teste no seu código de produção e também remover o ônus de manter arquivos de configuração XML adicionais.
PostScript
Escrever testes de integração para projetos de primavera é realmente muito mais fácil. O código no artigo refere -se ao meu próprio github.
Link de tradução: http://www.codeceo.com/article/spring-test-is-easy.html
Inglês original: teste -me se você pode nº 1 (Spring Framework)
Tradutor: Sandbox Wang, rede de codificação
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.