Injeção de mockock Mockito nos feijões da primavera
1. Visão geral
Este artigo mostrará como usar a injeção de dependência para inserir zombarias Mockito no Spring Beans para teste de unidade.
Em aplicativos do mundo real, onde os componentes geralmente dependem do acesso a sistemas externos, é importante fornecer isolamento de teste adequado, para que possamos nos concentrar em testar a funcionalidade de uma determinada unidade sem precisar envolver toda a hierarquia de classes para cada teste.
Injetar uma farsa é uma maneira limpa de introduzir esse isolamento.
2. Dependências do Maven
As seguintes dependências do Maven são necessárias para os testes de unidade e os objetos simulados:
org.springframework.boot
spring-boot-starter
1.3.1.RELEASE
org.springframework.boot
spring-boot-starter-test
1.3.1.RELEASE
test
org.mockito
mockito-core
2.21.0
Decidimos usar o Spring Boot neste exemplo, mas o Spring clássico também funcionará bem.
3. Escrevendo o teste
3.1. The Business Logic
Primeiro, vamos escrever a lógica de negócios que será testada:
@Service
public class NameService {
public String getUserName(String id) {
return "Real user name";
}
}
A classeNameService será injetada em:
@Service
public class UserService {
private NameService nameService;
@Autowired
public UserService(NameService nameService) {
this.nameService = nameService;
}
public String getUserName(String id) {
return nameService.getUserName(id);
}
}
Para este tutorial, as classes fornecidas retornam um único nome, independentemente do ID fornecido. Isso é feito para que não nos distraímos testando qualquer lógica complexa.
Também precisaremos de uma classe principal padrão do Spring Boot para verificar os beans e inicializar o aplicativo:
@SpringBootApplication
public class MocksApplication {
public static void main(String[] args) {
SpringApplication.run(MocksApplication.class, args);
}
}
3.2. Os testes
Agora vamos passar para a lógica de teste. Primeiro, precisamos configurar o contexto do aplicativo para os testes:
@Profile("test")
@Configuration
public class NameServiceTestConfiguration {
@Bean
@Primary
public NameService nameService() {
return Mockito.mock(NameService.class);
}
}
A anotação@Profile diz ao Spring para aplicar esta configuração apenas quando o perfil de “teste” estiver ativo. A anotação@Primary existe para garantir que essa instância seja usada em vez de uma real para autowiring. O próprio método cria e retorna uma simulação Mockito de nossa classeNameService.
Agora podemos escrever o teste de unidade:
@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MocksApplication.class)
public class UserServiceUnitTest {
@Autowired
private UserService userService;
@Autowired
private NameService nameService;
@Test
public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
Mockito.when(nameService.getUserName("SomeId")).thenReturn("Mock user name");
String testName = userService.getUserName("SomeId");
Assert.assertEquals("Mock user name", testName);
}
}
Usamos a anotação@ActiveProfiles para habilitar o perfil de “teste” e ativar a configuração simulada que escrevemos anteriormente. Por causa disso, o Spring autowire uma instância real da classeUserService, mas uma simulação da classeNameService. O teste em si é um teste JUnit + Mockito bastante típico. Configuramos o comportamento desejado do mock, depois chamamos o método que queremos testar e afirmamos que ele retorna o valor que esperamos.
Também é possível (embora não seja recomendado) evitar o uso de perfis de ambiente nesses testes. Para fazer isso, remova as anotações@Profile and @ActiveProfiles e adicione uma anotação@ContextConfiguration(classes = NameServiceTestConfiguration.class) à classeUserServiceTest.
4. Conclusão
O tutorial mostrou como injetar zombarias Mockito no Spring Beans. A implementação pode ser encontrada emexample GitHub project.