Como posso usar injeção com Mockito e JUnit 5?
No JUnit4, posso apenas usar a @RunWith(MockitoJUnitRunner.class)
Anotação. Em JUnit5 não há @RunWith
anotação?
Como posso usar injeção com Mockito e JUnit 5?
No JUnit4, posso apenas usar a @RunWith(MockitoJUnitRunner.class)
Anotação. Em JUnit5 não há @RunWith
anotação?
Respostas:
Existem diferentes maneiras de usar o Mockito - irei examiná-las uma por uma.
A criação de simulações manualmente com Mockito::mock
funciona independentemente da versão do JUnit (ou estrutura de teste para esse assunto).
Usar a anotação @Mock e a chamada correspondente MockitoAnnotations::initMocks
para criar simulações funciona independentemente da versão JUnit (ou estrutura de teste para esse assunto, mas Java 9 pode interferir aqui, dependendo se o código de teste termina em um módulo ou não).
JUnit 5 tem um modelo de extensão poderoso e Mockito publicou recentemente um sob o ID de grupo / artefato org.mockito : mockito-junit-jupiter .
Você pode aplicar a extensão adicionando @ExtendWith(MockitoExtension.class)
à classe de teste e anotando campos simulados com @Mock
. Do MockitoExtension
JavaDoc de:
@ExtendWith(MockitoExtension.class)
public class ExampleTest {
@Mock
private List list;
@Test
public void shouldDoSomething() {
list.add(100);
}
}
A documentação do MockitoExtension descreve outras maneiras de instanciar mocks, por exemplo, com injeção de construtor (se você rpefer campos finais em classes de teste).
As regras e os corredores JUnit 4 não funcionam no JUnit 5, portanto, o MockitoRule
e o corredor Mockito não podem ser usados.
@Test
necessidades para ser público ou "pacote privado" é bom o suficiente?
Use Mockito's MockitoExtension
. A extensão está contida em um novo artefato mockito-junit-jupiter
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
Ele permite que você escreva testes como faria com JUnit 4:
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
@ExtendWith(MockitoExtension.class)
class MyTest {
@Mock
private Foo foo;
@InjectMocks
private Bar bar; // constructor injection
...
}
@ExtendWith(MockitoExtension.class)
é equivalente @RunWith(MockitoJUnitRunner.class)
a do JUnit4
Existem diferentes maneiras de fazer, mas a maneira mais limpa e que também respeita a filosofia do JUnit 5 é criar um org.junit.jupiter.api.extension.Extension
para Mockito.
1) Criar mocks manualmente faz perder o benefício de verificações Mockito adicionais para garantir que você use a estrutura corretamente.
2) Chamar MockitoAnnotations.initMocks(this)
todas as classes de teste é um código padrão que poderíamos evitar.
E fazer essa configuração em uma classe abstrata também não é uma boa solução.
Ele acopla todas as classes de teste a uma classe base.
Se precisar de uma nova classe de teste base por bons motivos, você termina com uma hierarquia de classes de 3 níveis. Por favor, evite isso.
3) Regras de teste é uma especificidade JUnit 4.
Nem pense nisso.
E a documentação é clara sobre isso:
No entanto, se você pretende desenvolver uma nova extensão para o JUnit 5, use o novo modelo de extensão do JUnit Jupiter em vez do modelo baseado em regras do JUnit 4.
4) O Test Runner não é realmente a maneira de estender a estrutura JUnit 5.
O JUnit 5 simplificou o inferno dos executores do JUnit 4, fornecendo um modelo de extensão para escrever testes graças ao JUnit 5 Extensions.
Nem pense nisso.
Portanto, favoreça o org.junit.jupiter.api.extension.Extension
caminho.
EDITAR: Na verdade, o Mockito agrupa uma extensão Júpiter: mockito-junit-jupiter
Então, muito simples de usar:
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class FooTest {
...
}
Aqui está um complemento à excelente resposta de Jonathan.
Ao adicionar o mockito-junit-jupiter
artefato como dependência , o uso @ExtendWith(MockitoExtension.class)
produziu a seguinte exceção à medida que o teste é executado:
java.lang.NoSuchMethodError: org.junit.platform.commons.support.AnnotationSupport.findAnnotation (Ljava / util / Opcional; Ljava / lang / Class;) Ljava / util / Opcional;
O problema é que mockito-junit-jupiter
depende de duas bibliotecas independentes. Por exemplo mockito-junit-jupiter:2.19.0
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.19.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.1.0</version>
<scope>runtime</scope>
</dependency>
O problema foi que eu usei junit-jupiter-api:5.0.1
.
Portanto, como junit-jupiter-api
ainda se move frequentemente em termos de API, certifique-se de depender da mesma versão da junit-jupiter-api
qual mockito-junit-jupiter
depende.
mockito-junit-jupiter
puxa a versão adequada de junit-jupiter-api
?
mockito-junit-jupiter:2.19.0
. Enquanto as versões de JUnit Jupiter começam com 5
. mockito-junit-jupiter deve ter especificado em seu identificador de artefato as duas coisas (versão Mockito e versão JUnit Júpiter) para tornar as coisas mais claras. Por exemplo, mockito-junit-jupiter-5.1:2.19.0
para transmitir que a biblioteca foi projetada para JUnit Jupiter 5.1.
MockitoExtension
não parece existir na mockito-core
versão 3.0.0.
mockito-junit-jupiter
Você tem que usar a nova @ExtendWith
anotação.
Infelizmente, ainda não há nenhuma extensão lançada. No github, você pode ver uma implementação beta da extensão. como um exemplo de teste de demonstração .