Estou recebendo a seguinte exceção durante a execução dos testes. Estou usando o Mockito para zombar. As dicas mencionadas pela biblioteca Mockito não estão ajudando.
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.a.b.DomainTestFactory.myTest(DomainTestFactory.java:355)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
at a.b.DomainTestFactory.myTest(DomainTestFactory.java:276)
..........
Código de teste de DomainTestFactory
. Quando executo o teste a seguir, vejo a exceção.
@Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
Mockito.when(mainModel.getList()).thenReturn(getSomeList()); // Line 355
}
private List<SomeModel> getSomeList() {
SomeModel model = Mockito.mock(SomeModel.class);
Mockito.when(model.getName()).thenReturn("SomeName"); // Line 276
Mockito.when(model.getAddress()).thenReturn("Address");
return Arrays.asList(model);
}
public class SomeModel extends SomeInputModel{
protected String address;
protected List<SomeClass> properties;
public SomeModel() {
this.Properties = new java.util.ArrayList<SomeClass>();
}
public String getAddress() {
return this.address;
}
}
public class SomeInputModel{
public NetworkInputModel() {
this.Properties = new java.util.ArrayList<SomeClass>();
}
protected String Name;
protected List<SomeClass> properties;
public String getName() {
return this.Name;
}
public void setName(String value) {
this.Name = value;
}
}
Respostas:
Você está aninhando zombaria dentro de zombaria. Você está ligando
getSomeList()
, o que faz algumas zombarias, antes de terminar a zombariaMyMainModel
. Mockito não gosta quando você faz isso.Substituir
com
Para entender por que isso causa um problema, você precisa saber um pouco sobre como o Mockito funciona e também estar ciente de que expressões e instruções de ordem são avaliadas em Java.
O Mockito não pode ler o seu código-fonte, portanto, para descobrir o que você está pedindo, ele depende muito do estado estático. Quando você chama um método em um objeto simulado, o Mockito registra os detalhes da chamada em uma lista interna de chamadas. O
when
método lê a última dessas invocações da lista e registra essa invocação noOngoingStubbing
objeto que retorna.A linha
causa as seguintes interações com o Mockito:
mainModel.getList()
é chamado,when
é chamado,thenReturn
é chamado noOngoingStubbing
objeto retornado pelowhen
método.O
thenReturn
método pode instruir a simulação que recebeu por meio doOngoingStubbing
método para manipular qualquer chamada adequada aogetList
método para retornarsomeModelList
.De fato, como o Mockito não pode ver seu código, você também pode escrever sua zombaria da seguinte maneira:
Esse estilo é um pouco menos claro de ler, especialmente porque, nesse caso,
null
ele deve ser convertido, mas gera a mesma sequência de interações com o Mockito e alcançará o mesmo resultado da linha acima.No entanto, a linha
causa as seguintes interações com o Mockito:
mainModel.getList()
é chamado,when
é chamado,mock
deSomeModel
é criado (no interiorgetSomeList()
),model.getName()
é chamado,Nesse ponto, Mockito fica confuso. Ele pensou que você estava zombando
mainModel.getList()
, mas agora você está dizendo que deseja zombar domodel.getName()
método. Para Mockito, parece que você está fazendo o seguinte:Isso parece bobagem,
Mockito
pois não pode ter certeza do que você está fazendomainModel.getList()
.Observe que não chegamos à
thenReturn
chamada do método, pois a JVM precisa avaliar os parâmetros desse método antes de poder chamá-lo. Nesse caso, isso significa chamar ogetSomeList()
método.Geralmente, é uma má decisão de projeto confiar no estado estático, como Mockito, porque pode levar a casos em que o Princípio da menor surpresa é violado. No entanto, o design de Mockito resulta em zombarias claras e expressivas, mesmo que algumas vezes causem espanto.
Finalmente, as versões recentes do Mockito adicionam uma linha extra à mensagem de erro acima. Essa linha extra indica que você pode estar na mesma situação que esta pergunta:
fonte
Para zombar de métodos nulos, tente abaixo:
fonte