Как избежать дублирования кода при использовании насмешек в юнит-тестах - PullRequest
8 голосов
/ 06 января 2009

Я использую инъекцию зависимостей для предоставления макетов для кода вне тестируемого моего класса. Я снова и снова пишу много одного и того же кода, поскольку мне нужно макетировать AuthProvider, ConfigurationManager и т. Д., Которые используются в методе, который я хочу протестировать. Метод содержит ветви (if-then-else), и поэтому у меня есть несколько тестов для проверки всех путей выполнения метода. Я создаю экземпляры каждого из макетов несколько раз (по одному в каждом методе тестирования), но мне интересно, если это неправильно? Также я возлагаю надежды на макеты и предустановленные ответы, которые, очевидно, в основном копируются, поскольку такие вызовы, как AuthProvider.Authenticate (), вызываются в каждом методе

В каждом методе я устанавливаю фиктивное хранилище, и в конце каждого метода я проверяю фиктивное хранилище. Должен ли я иметь какую-то фабрику для создания этих макетов вместе с установкой их ожиданий и возвращаемых значений, и если да, то как?

Для реализации макетов я использую RhinoMocks.

Ответы [ 5 ]

5 голосов
/ 06 января 2009

«создание экземпляров каждого из насмешек несколько раз» не является проблемой. Объекты свободны.

Просто убедитесь, что вы не определяете ложные классы много раз. Занятия дорогие.

Кроме того, у вас есть метод setUp в TestCase, который позволяет вам создать прибор, который используется всеми тестами. Да, он перестраивается для каждого теста. Нет, это не проблема, если не мучительно медленно.

2 голосов
/ 21 мая 2009

Предполагая, что вы используете NUnit, вы можете использовать переменные экземпляра для ваших Mocks и сбросить их в Setup / Teardown. Если вы видите повторяющиеся шаблоны, то делайте то, что вы делаете с рабочим кодом: рефакторинг и извлечение вспомогательных методов, которые выражают то, что вы пытаетесь достичь (если вообще нет общности, тогда проблема с дизайном рабочего кода). 1001 *

Если в настройке имеются значительные подразделения, рассмотрите возможность написания более одного тестового класса для вашего производственного класса.

Наконец, подумайте, не слишком ли занят ваш производственный класс, и какую-то часть поведения следует извлечь во вспомогательный объект.

Слушайте тесты!

1 голос
/ 06 января 2009

Вот мой дубль ..

Я бы не использовал mock в этом случае ... Я бы использовал фабричный метод, чтобы возвратить ложную реализацию класса, и использовал бы внедрение зависимостей, чтобы использовать эту реализацию вместо этого ... таким образом, вы избежали бы дублирования и могли бы повторно использовать эту реализацию снова n снова ... снова эта фабричная реализация должна быть реорганизована должным образом, т.е. без дублирования ..

Придурки, я думаю, их следует использовать, когда вы тестируете какое-то динамическое поведение ... что-то вроде ... сделал ли метод в подсистеме вызванным, когда я выполняю какое-то действие на SUT ... и позже вызову verify () для проверки это поведение ... есть также хорошая статья о Мартине Фолвере блики Мок не тупики

0 голосов
/ 06 января 2009

Среды записи и воспроизведения, такие как EasyMock, перестают работать, если вы не устанавливаете ожидание для ложного вызова. Но фреймворки, такие как Mockito, просто записывают все вызовы и позволяют проверять только те, которые имеют значение. Поэтому вам не нужно устанавливать ожидание для всех методов во всех тестах.

И возвращаясь к вашей проблеме создания экземпляров Mocks в каждом методе тестирования, есть лучший способ, чем использование метода setUp (). Mockito предоставляет аннотацию @Mock. Итак, вы объявляете свои переменные (как поля) как: Репозиторий @Mock РепозиторийMock

и просто вызовите initMocks () в setUp (). Все объявленные фиктивные объекты автоматически доступны в ваших тестах без явного создания имитаторов.

0 голосов
/ 06 января 2009

Возможно, вы захотите использовать тест в стиле AAA, чтобы у вас было несколько тестов с общей настройкой. Вот хороший пример.

...