Незаконченное раскорчевки обнаружить в Mockito
Я получаю следующее исключение во время выполнения тестов. Я использую Mockito для насмешек. Намеки, упомянутые библиотекой Mockito, не помогают.
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)
..........
тестовый код из DomainTestFactory. Когда я запускаю следующий тест, я вижу исключение
@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;
}
}
1 ответ:
вы гнездитесь насмешливо внутри насмешки. Ты звонишь
getSomeList()
, который делает некоторые насмешки, прежде чем вы закончите насмешки дляMyMainModel
. Мокито не любит, когда ты так делаешь.заменить
@Test public myTest(){ MyMainModel mainModel = Mockito.mock(MyMainModel.class); Mockito.when(mainModel.getList()).thenReturn(getSomeList()); --> Line 355 }
С
@Test public myTest(){ MyMainModel mainModel = Mockito.mock(MyMainModel.class); List<SomeModel> someModelList = getSomeList(); Mockito.when(mainModel.getList()).thenReturn(someModelList); }
чтобы понять, почему это вызывает проблему, вам нужно немного знать о том, как работает Mockito, а также знать, в каком порядке выражения и операторы оцениваются в Java.
Mockito не могу прочитать ваш исходный код, поэтому, чтобы выяснить, что вы просите его сделать, он во многом зависит от статического состояния. При вызове метода на макет объекта, Mockito записывает сведения о вызове во внутренний список вызовов. Элемент
when
метод чтения последнего из этих вызовов из списка и записывает этот вызов вOngoingStubbing
объект, который она возвращает.строку
Mockito.when(mainModel.getList()).thenReturn(someModelList);
вызывает следующие взаимодействия с Mockito:
- Mock метод
mainModel.getList()
называется- статический метод
when
называется- метод
thenReturn
о строкаMockito.when(mainModel.getList()).thenReturn(getSomeList());
вызывает следующие взаимодействия с Mockito:
- макет метод
mainModel.getList()
называется- статический метод
when
is звонил,- новая
mock
наSomeModel
создается (внутриgetSomeList()
),- макет метод
model.getName()
называетсяв этот момент Мокито запутывается. Он думал, что ты издеваешься
mainModel.getList()
, но теперь вы говорите, что хотите высмеятьmodel.getName()
метод. В Mockito, похоже, вы делаете следующее:when(mainModel.getList()); // ... when(model.getName()).thenReturn(...);
это выглядит глупо
Mockito
как он не может быть уверен, что вы делаете сmainModel.getList()
.Примечание. чтобы мы не добрались до
thenReturn
вызов метода, так как JVM должен оценить параметры этого метода, прежде чем он сможет вызвать метод. В этом случае это означает вызовgetSomeList()
метод.как правило, это плохое проектное решение полагаться на статическое состояние, как это делает Mockito, потому что это может привести к случаям, когда нарушается принцип наименьшего удивления. Тем не менее, дизайн Mockito действительно делает для ясной и выразительной насмешки, даже если это приводит к удивлению иногда.
наконец, последние версии Mockito добавляют дополнительную строку к сообщению об ошибке выше. Эта дополнительная строка указывает, что вы можете быть в той же ситуации, что и этот вопрос:
3: вы заглушаете поведение другого макета внутри перед инструкцией "thenReturn", если она завершена