Mockito: использование метода "thenReturn" для возврата макета не работает
Я столкнулся с тем, что, по моему мнению, может быть ошибкой с Mockito, но задавался вопросом, может ли кто-нибудь еще пролить свет на то, почему этот тест не работает.
В принципе, у меня есть два объекта, например:
public class FirstObject {
private SecondObject secondObject;
public SecondObject getSecondObject() { return secondObject; }
}
public class SecondObject {
private String name;
public String getName() { return name; }
}
Первый объект издевается через аннотацию и метод before:
@Mock
FirstObject mockedFirstObject;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
Второй объект издевается по методу:
public SecondObject setupMockedSecondObject() {
SecondObject secondObject = Mockito.mock(SecondObject.class);
Mockito.when(secondObject.getName()).thenReturn("MockObject");
return secondObject;
}
Когда thenReturn
содержит прямой вызов этого метода для настройки и получения макета второго объекта, он терпит неудачу:
@Test
public void notWorkingTest() {
Mockito.when(mockedFirstObject.getSecondObject()).thenReturn(setupMockedSecondObject());
Assert.assertEquals(mockedFirstObject.getSecondObject().getName(), "MockObject");
}
Но, когда макет, возвращенный тем же методом, назначается локальной переменной, которая используется в thenReturn
, она работает:
@Test
public void workingTest() {
SecondObject mockedSecondObject = setupMockedSecondObject();
Mockito.when(mockedFirstObject.getSecondObject()).thenReturn(mockedSecondObject);
Assert.assertEquals(mockedFirstObject.getSecondObject().getName(), "MockObject");
}
Мы делаем что-то неправильно или это действительно ошибка/ограничение в Mockito? Есть ли умышленная причина, по которой это не работает?
Ответы
Ответ 1
Это действительно ограничение Mockito, и на него ссылаются в их FAQ:
Могу ли я thenReturn()
встроить mock()
?
К сожалению, вы не можете этого сделать:
when(m.foo()).thenReturn(mock(Foo.class));
// ^
Причина в том, что обнаружение незавершенного штамповки не будет работать, если мы разрешим эту конструкцию. Мы рассматриваем это как "компромисс" валидации структуры (см. Также предыдущую запись в FAQ). Однако вы можете слегка изменить код, чтобы он работал:
//extract local variable and start smiling:
Foo foo = mock(Foo.class);
when(m.foo()).thenReturn(foo);
Обходной путь, как уже упоминалось, заключается в сохранении желаемого возвращаемого значения в локальной переменной, как и вы.
То, как я понимаю, это то, что Mockito проверяет использование, которое вы делаете, каждый раз, когда вы вызываете его методы. Когда вызывается другой метод во время текущего процесса прерывания, вы нарушаете его процесс проверки.