#java #junit #mocking #mockito #stubbing
#java #юнит #насмешливый #мокито #заглушка
Вопрос:
Я экспериментирую с преобразованием некоторых моих модульных тестов с использования JMock на использование Mockito и столкнулся с несколькими препятствиями.
Во-первых, в моих тестах при использовании JMock проверка и возврат заглушки происходят за один шаг следующим образом
contextMockery.checking(new Expectations() {{
oneOf(dateUtilityService).isBeforeToday(URGENT_DATE);
will(returnValue(true));
}});
Это, по сути, проверяет, вызывается ли метод, и одновременно возвращает заданное значение. Тест завершается неудачей, если метод isBeforeToday НЕ вызывается и одновременно возвращает мое законсервированное значение true. Принимая во внимание, что при использовании Mockito я должен убедиться, что вызывается метод, а затем вернуть мое сохраненное значение отдельными шагами, которые в значительной степени дублируют следующие:
doReturn(true).when(dateUtilityService).isBeforeToday(URGENT_DATE);
verify(dateUtilityService).isBeforeToday(URGENT_DATE);
Неужели нет способа сделать это за один шаг?
Во-вторых, если я забуду указать вызов метода для одного из моих макетов в своих ожиданиях, JMock не пройдет тест с «Неожиданным исключением вызова», что, на мой взгляд, правильно, тогда как Mockito с радостью пройдет тест, если я явно не проверю, что вызов метода для макета никогда не должен происходить, это правильно (кажется неправильным)? Есть ли способ сообщить mockito, чтобы он провалил тест, если неожиданные вызовы методов выполняются для моих издевательских зависимостей?
Комментарии:
1. Просто из любопытства, вы также рассматривали возможность преобразования тестов в JMockit? Синтаксис намного ближе к JMock :
new Expectations() {{ dateUtilityService.isBeforeToday(URGENT_DATE); result = true; }};
.
Ответ №1:
1.
Когда вы заглушаете вызов метода, метод проверки обычно не требуется — вы должны проверить действие на основе возвращаемого значения (в вашем случае что-то может произойти или что-то будет возвращено, когда dateUtilityService вернет true — проверьте это вместо проверки взаимодействия с макетом.
Документация Mockito также говорит об этом. http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#2
2.
Это фактически приводит к хрупким тестам и не рекомендуется делать что-либо с mockito. Вот почему нет никакого способа установить такое поведение.
Смотрите http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#8
Комментарии:
1. Так что это имеет смысл в некоторых случаях (например, в том, который я показал), когда заглушка изменяет значение вашего возвращаемого типа. Но, как я упоминал во второй части моего вопроса, если я забуду заглушить вызов метода (который может не изменять возвращаемое значение) в моем тесте, я хотел бы знать об этом, чтобы я мог сделать осознанный выбор: либо заглушить вызов, либо сообщить тесту, что он должен никогда не будет вызван.
2. @ClintonBosch Вы можете добавить вызов
verifyNoMoreInteractions()
в конце вашего метода тестирования, чтобы обнаружить любые неотправленные вызовы.3. С тех пор, как я начал использовать Mockito (я использовал JMock с 2007 года или даже раньше… Я не помню), я заметил зеленые тесты, в которых коллеги забыли позвонить сотруднику, я слышал предложения типа «модульные тесты иногда дают ложное срабатывание, лучше проводить интеграционные тесты». Может быть, лучше использовать такой инструмент, как JMock, и попытаться избежать этих «хрупких тестов» другим способом, вместо того чтобы использовать такие слабые инструменты проектирования, как Mockito.