У меня есть закрытый метод в моем тестовом классе, который создает часто используемый Bar
объект. Bar
Конструктор вызывает someMethod()
метод в моем издевались объекта:
private @Mock Foo mockedObject; // My mocked object
...
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
}
В некоторых моих тестовых методах, которые я хочу проверить, someMethod
также вызывался именно этим тестом. Что-то вроде следующего:
@Test
public void someTest() {
Bar bar = getBar();
// do some things
verify(mockedObject).someMethod(); // <--- will fail
}
Это терпит неудачу, потому что высмеянный объект someMethod
вызвал дважды. Я не хочу, чтобы мои тестовые методы заботились о побочных эффектах моего getBar()
метода, поэтому было бы разумно сбросить мой фиктивный объект в конце getBar()
?
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
reset(mockedObject); // <-- is this OK?
}
Я спрашиваю, потому что документация предлагает сброс фиктивных объектов, как правило, свидетельствует о плохих тестах. Тем не менее, это чувствует себя хорошо для меня.
альтернатива
Альтернативный выбор, кажется, вызывает:
verify(mockedObject, times(2)).someMethod();
что, на мой взгляд, заставляет каждый тест знать об ожиданиях getBar()
, без выгоды.
Mockito.clearInvocations(T... mocks)
Извлечено из документов mockito .
Я советую вам избегать использования
reset()
. По моему мнению, если вы дважды вызываете метод SomeMethod, это следует проверить (возможно, это доступ к базе данных или другой длительный процесс, о котором вы хотите позаботиться).Если вы действительно не заботитесь об этом, вы можете использовать:
Обратите внимание, что это последнее может привести к ложному результату, если вы вызываете someMethod из getBar, а не после (это неправильное поведение, но тест не будет неудачным).
источник
verify
свой частный метод (что, я согласен, вероятно, не относится к этому). Я приветствую ваши комментарии о том, изменится ли ваш ответ.Точно нет. Как это часто бывает, трудность, с которой вы сталкиваетесь при написании чистого теста, заключается в серьезном красном флажке дизайна вашего рабочего кода. В этом случае лучшим решением будет рефакторинг вашего кода, чтобы конструктор Bar не вызывал никаких методов.
Конструкторы должны конструировать, а не выполнять логику. Возьмите возвращаемое значение метода и передайте его в качестве параметра конструктора.
будет выглядеть так:
Если это приведет к дублированию этой логики во многих местах, подумайте о создании фабричного метода, который можно протестировать независимо от вашего объекта Bar:
Если этот рефакторинг слишком сложен, то использование reset () - хороший способ обойти это. Но давайте будем ясны - это говорит о том, что ваш код плохо спроектирован.
источник