Podczas przeprowadzania testów otrzymuję następujący wyjątek. Używam Mockito do kpiny. Podpowiedzi, o których wspomina biblioteka Mockito, nie pomagają.
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)
..........
Kod testowy od DomainTestFactory
. Kiedy uruchamiam następujący test, widzę wyjątek.
@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;
}
}
Odpowiedzi:
Kpisz sobie z gniazda wewnątrz kpiny. Dzwonisz
getSomeList()
, co trochę kpi, zanim skończysz kpićMyMainModel
. Mockito nie lubi, kiedy to robisz.Zastąpić
z
Aby zrozumieć, dlaczego powoduje to problem, musisz trochę wiedzieć, jak działa Mockito, a także mieć świadomość, w jakiej kolejności wyrażenia i instrukcje są oceniane w Javie.
Mockito nie może odczytać twojego kodu źródłowego, więc aby dowiedzieć się, o co go prosisz, opiera się w dużej mierze na stanie statycznym. Kiedy wywołujesz metodę na obiekcie pozorowanym, Mockito zapisuje szczegóły wywołania na wewnętrznej liście wywołań.
when
Metoda odczytuje ostatni z tych inwokacji z listy i zapisuje tę inwokację wOngoingStubbing
obiekcie to powraca.Linia
powoduje następujące interakcje z Mockito:
mainModel.getList()
jest ,when
,thenReturn
jest wywoływana naOngoingStubbing
obiekcie zwróconym przezwhen
metodę.thenReturn
Sposób może następnie nakazać pozornie jest odbierany za pomocąOngoingStubbing
sposobu obsługi dowolnego odpowiedniego połączenia dogetList
sposobu powrotusomeModelList
.W rzeczywistości, ponieważ Mockito nie widzi twojego kodu, możesz również napisać mockowanie w następujący sposób:
Ten styl jest nieco mniej czytelny, zwłaszcza że w tym przypadku
null
musi zostać rzucony, ale generuje tę samą sekwencję interakcji z Mockito i osiąga ten sam wynik, co powyższa linia.Jednak linia
powoduje następujące interakcje z Mockito:
mainModel.getList()
jest ,when
,mock
zSomeModel
(wewnątrzgetSomeList()
),model.getName()
jest metoda Mock ,W tym momencie Mockito jest zdezorientowany. Myślał, że kpisz
mainModel.getList()
, ale teraz mówisz mu, że chcesz kpić zmodel.getName()
metody. Dla Mockito wygląda na to, że wykonujesz następujące czynności:To wygląda głupio,
Mockito
ponieważ nie można być pewnym, z czym robiszmainModel.getList()
.Zauważ, że nie dotarliśmy do
thenReturn
wywołania metody, ponieważ maszyna JVM musi ocenić parametry tej metody, zanim będzie mogła wywołać metodę. W tym przypadku oznacza to wywołaniegetSomeList()
metody.Ogólnie rzecz biorąc, poleganie na stanie statycznym jest złą decyzją projektową, tak jak robi to Mockito, ponieważ może to prowadzić do przypadków, w których naruszona jest zasada najmniejszego zdziwienia. Jednak projekt Mockito zapewnia jasne i wyraziste kpiny, nawet jeśli czasami prowadzi do zdziwienia.
Wreszcie, ostatnie wersje Mockito dodają dodatkową linię do powyższego komunikatu o błędzie. Ta dodatkowa linia wskazuje, że możesz być w takiej samej sytuacji, jak to pytanie:
źródło
Aby kpić z metod void, wypróbuj poniższe:
źródło