Это заслуга разработчиков Mockito в том, что передача макета, похоже, проще, чем создание реальной строки. Тем не менее, создание реальной строки по-прежнему является самым умным вариантом для вашего теста.
Вы правильно заметили, что строка является final
, поэтому Mockito не может использовать прокси или поколение байткодом молча создать подкласс для него. Вместо этого вы должны были бы использовать Powermock, что на самом деле переписать байт-код вашего класса-под-тестом, используя пользовательский загрузчик классов, чтобы использовать ваш mocked String.length() вместо фактической реализации. В любом случае, это очень много работы, чтобы имитировать простую строку, и, возможно, это займет больше времени и памяти теста, чем альтернатива.
Даже если String не был final
, вы все равно будете писать хрупкий тест, потому что вы (предположительно) только издеваетесь над подмножеством String. В этом гипотетическом, вы могли бы написать:
when(mockString.length()).thenReturn(2048);
, но потом, в один прекрасный день, ваша реализация превращается в:
public boolean isStringValid(String input) {
// Handle Unicode surrogate pairs.
return input.codePointCount(0, input.length()) <= 1024; // NOT 2048
}
... и вдруг ваш тест ошибочно проходит, потому что Mockito видит unmocked codePointCount
и возвращается его значение по умолчанию int
. 0. Это одна из причин того, что тесты с использованием неполных mocks менее устойчивы и менее ценны, чем тесты с использованием реальных объектов.
Но как насчет полных издевательств? Тогда вы могли бы высмеять codePointCount
и так далее. Взятый к его логическому завершению, вы могли представить себе объект смешного String, который настолько продвинут, он правильно возвращает значение для абсолютно любого вызова, который вы ему даете. В этот момент вы переопределили строку изнутри, вероятно, за счет удобочитаемости, и потратили много инженерных часов, воспроизводя одну из самых проверенных, наиболее очевидных реализаций в истории Java по очень небольшой причине. Если что-нибудь, , что кажется довольно глупым для меня.
Несколько советов:
Не смейся реализации вы не владеете. Mockito по-прежнему привязан к отметкам final
в реализациях, которые он издевается, например, так насмехается над другими типами - это плохая привычка. Когда детали реализации других команд могут нарушить ваши тесты, это очень плохой знак.
Не издевайтесь над объектами, если вы можете использовать настоящий, проверенный, аутентичный экземпляр. В этом случае редко бывает веской причиной издеваться над этим, и это, скорее всего, сделает ваш тест излишне хрупким.
В частности, не издевайтесь над объектами данных. Например, они полагаются на getFoo
, соответствующие setFoo
, а также могут рассчитывать на equals
и hashCode
.В любом случае хорошо продуманные объекты данных не имеют внешних зависимостей.
Mock интерфейсы вместо классов реализации, когда вы можете. Это изолирует вас от деталей реализации, которые изменяют работу ваших макетов.
Если вы обнаружите, что объект данных, который вызывает служебные вызовы или использует ресурсы, которые не подходят для тестирования, помните, что вы можете реорганизовать классы для повышения тестовой способности, например, определенные классы или извлечение интерфейсов и сделать custom reusable test doubles. Ваши тесты должны быть первоклассными пользователями ваших классов, и ваша прерогатива изменяет классы, которые вы контролируете (или обертываете классы, которые вы не контролируете) для проверки. Я часто обнаружил, что это упрощает использование этих классов в производстве.
Я не понимаю проблему, не могли бы вы объяснить немного больше или написать какой-нибудь код? Если вы пытаетесь бросить и исключить и проверить его, вы должны добавить параметр в аннотацию @Test (expected = YourException.class) –
Почему передача строки глупа? Я видел слишком много злоупотреблений макетом. –
Для записи есть аналогичный вопрос [Как издеваться над String using mockito?] (Http://stackoverflow.com/q/1079239/1426891) уже на StackOverflow. Я не думаю, что это дубликат, хотя этот вопрос касается насмешливой стратегии, а не возможностей библиотеки. –