Используйте Mockito, чтобы убедиться, что после метода ничего не вызывается.
-
21-08-2019 - |
Вопрос
Я использую Mockito для написания модульного теста на Java, и мне хотелось бы убедиться, что определенный метод является последний вызвал объект.
Я делаю что-то вроде этого в тестируемом коде:
row.setSomething(value);
row.setSomethingElse(anotherValue);
row.editABunchMoreStuff();
row.saveToDatabase();
В моем макете меня не волнует порядок редактирования всего в строке, но очень важно, чтобы я нет попытайтесь сделать с ним что-нибудь еще после того, как я его сохранил.Есть ли хороший способ сделать это?
Обратите внимание, что я не ищуverifyNoMoreInteractions:он не подтверждает, что saveToDatabase вызывается последним, а также завершается сбоем, если я вызываю в строке что-либо, что не проверяю явно.Я хотел бы иметь возможность сказать что-то вроде:
verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verifyTheLastThingCalledOn(row).saveToDatabase();
Если это поможет, я перехожу на Mockito из теста JMock, который делал это:
row.expects(once()).method("saveToDatabase").id("save");
row.expects(never()).method(ANYTHING).after("save");
Решение
Я думаю, что это требует более индивидуальной работы.
verify(row, new LastCall()).saveToDatabase();
а потом
public class LastCall implements VerificationMode {
public void verify(VerificationData data) {
List<Invocation> invocations = data.getAllInvocations();
InvocationMatcher matcher = data.getWanted();
Invocation invocation = invocations.get(invocations.size() - 1);
if (!matcher.matches(invocation)) throw new MockitoException("...");
}
}
Предыдущий ответ:
Ты прав.verifyNoMoreInteractions — это то, что вам нужно.
verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verify(row).editABunchMoreStuff();
verify(row).saveToDatabase();
verifyNoMoreInteractions(row);
Другие советы
Не на 100% по теме, но я просто хотел найти противоположность проверке, и это был единственный релевантный результат, в итоге я был после Mockito.verifyZeroInteractions(mock);
На случай, если кто-нибудь еще окажется здесь в поисках этого...
Этот вопрос побудил меня внести некоторые улучшения в Проверки API в JMockit (доступно в предстоящем выпуске 0.983).
Решение, которое я придумал, позволяет вам написать (в тестовом методе):
new VerificationsInOrder() {{
unverifiedInvocations();
row.saveToDababase();
}};
...если вы хотите только убедиться, что определенный метод вызывается после всего остального.Чтобы убедиться, что это происходит до для всех остальных вызовов просто переместите вызов наверх.Фактически это применимо к любой последовательности последовательных вызовов.
Если в дополнение к вышеуказанной проверке вы также хотите проверить, что некоторые другие методы вызываются в любом порядке, вторая проверки блок можно добавить в тест (до или после другого блока, не имеет значения):
new Verifications() {{
row.setSomething(value);
row.setSomethingElse(anotherValue);
}};
Хотя этот синтаксис немного длинный из-за использования анонимных внутренних классов, он одновременно прост и гибок;обратите внимание, как это добавляет структуру тесту и позволяет избежать повторения вызовов методов (например, verify(...)
).Это нечто большее, чем я описал здесь (сопоставители Hamcrest, счетчик вызовов и т. д.), и это не ограничивается проверкой методов экземпляра (статические методы и конструкторы можно имитировать и проверять таким же образом).