Как проверить, что конкретный метод не был вызван, используя Mockito?
Как проверить, что метод не был вызван на зависимости объекта?
У меня есть следующий код:
public interface Dependency {
void someMethod();
}
public class Foo {
public void bar(final Dependency d) {
...
}
}
Я создаю тест для класса Foo:
public class FooTest {
@Test
public void dependencyIsNotCalled() {
final Foo foo = new Foo(...);
final Dependency dependency = mock(Dependency.class);
foo.bar(dependency);
**// как здесь проверить, что someMethod не был вызван??**
}
}
Как мне реализовать проверку, что метод someMethod на зависимости не был вызван в процессе выполнения метода bar?
5 ответ(ов)
Вы можете использовать второй аргумент метода Mockito.verify
, чтобы указать, сколько раз вы ожидаете вызов метода. Например, если вы хотите убедиться, что метод someMethod
не был вызван, вы можете написать код, как в следующем примере:
Mockito.verify(dependency, Mockito.times(0)).someMethod();
Здесь Mockito.times(0)
указывает, что someMethod
не должен был быть вызван ни разу.
Во-первых, вам всегда следует импортировать статические методы Mockito, это сделает ваш код гораздо более читабельным и интуитивно понятным:
import static org.mockito.Mockito.*;
Существует множество способов проверить взаимодействия с моками, однако, на мой взгляд, более чистым вариантом будет использование метода:
verify(yourMock, times(0)).someMethod();
При этом, в других тестах вы можете использовать его для проверки определенного количества вызовов таким образом:
verify(yourMock, times(5)).someMethod();
Альтернативы этому:
verify(yourMock, never()).someMethod();
Кроме того, когда вам действительно нужно убедиться, что определенный мок-объект не был вызван вообще, вы можете использовать:
verifyZeroInteractions(yourMock);
Обратите внимание:
метод verifyZeroInteractions(Object... mocks)
устарел начиная с версии 3.0.1. Теперь рекомендуется использовать:
verifyNoInteractions(yourMock);
В качестве более общего подхода, я обычно использую блок @After
в своих тестах:
@After
public void after() {
verifyNoMoreInteractions(<ваш mock1>, <ваш mock2>...);
}
Таким образом, тест может свободно проверять только то, что должно быть вызвано.
Также я заметил, что часто забывал проверять "отсутствие взаимодействий", и лишь позже обнаруживал, что вызывались вещи, которые не должны были быть вызваны.
Поэтому я нахожу этот подход полезным для выявления всех неожиданных вызовов, которые не были специально проверены.
Обе методы verifyNoMoreInteractions()
и verifyZeroInteractions()
имеют одинаковую реализацию, которая заключается в следующем:
public static transient void verifyNoMoreInteractions(Object mocks[]) {
MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}
public static transient void verifyZeroInteractions(Object mocks[]) {
MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}
Таким образом, вы можете использовать любой из этих методов на объекте-моке или массиве объектов-моков, чтобы проверить, что методы не были вызваны с использованием мок-объектов.
Есть несколько вариантов, в зависимости от вашего случая использования.
Если вы хотите убедиться, что метод someMethod
не был вызван на dependency
, используйте следующий код:
verify(dependency, times(0)).someMethod();
Либо, более читаемый вариант:
verify(dependency, never()).someMethod();
Если вам нужно, чтобы не произошло никаких взаимодействий с конкретной зависимостью, используйте следующий код:
verifyNoInteractions(dependency);
Если у зависимости есть несколько методов, и вы хотите убедиться, что был вызван только ожидаемый метод и ничего больше, используйте:
verify(dependency, times(1)).someMethod();
verifyNoMoreInteractions(dependency);
Как протестировать класс с приватными методами, полями или внутренними классами?
Как замокировать методы с возвращаемым типом void с помощью Mockito
Как проверить, что в JUnit-тестах выбрасывается определенное исключение?
"Как сделать так, чтобы имитируемый метод возвращал аргумент, который был ему передан?"
Что значит 'synchronized'?