2012-06-11 3 views
1

У меня проблема с простой тестовой конструкцией, которую я хотел бы раз и навсегда решить.Как написать Unit Test для менеджера, запускающего dao?

Я довольно привык к регулярному шаблону проектирования Java, где есть Manager interface (или фасад) и набор DAO interfaces. Конкретная реализация ManagerImpl использует конкретные реализации DaoImpl.

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

Я был в состоянии издеваться над некоторыми методами моего менеджера, используя mockito, но так как метод Test Under (или так называемый System Under Test) использует DAO внутри себя, мне тоже пришлось бы издеваться над DAO. К сожалению, я не могу этого сделать, не устанавливая конкретную реализацию DAO в моем менеджере, например myManager.setMyDao(mockedDao), но теперь мне придется вытащить этот метод setMyDao в интерфейс, что, конечно же, разрывает инкапсуляцию и делает мои чистые и совершенные интерфейсы похожими на мусор.

Вопрос в следующем: Как насмехаться с DAO в тестах при сохранении чистой Manager-Dao архитектуры?

ответ

1

Вы должны выполнить единичные испытания бетонных конструкций, то есть ManagerImplTest, которые будут явно создавать ManagerImpl, и поэтому у вас есть все методы setMyDao, доступные для mocks. Ваш тест не будет знать о Manager interface.

Кстати, не всегда необходимо создавать интерфейсы для всего. В большинстве случаев будет существовать только одна реализация менеджеров и даос. Если нет какой-либо другой сильной причины (например, прокси-сервера Spring AOP или разделения зависимостей), я думаю, лучше не создавать интерфейсы для всего ради простоты.

+0

+1: действительная точка на тестировании 'Impl', однако совет по избавлению от интерфейса * может * быть короткоживущим, когда оказывается, что« менеджер »является зависимостью для какого-либо другого объекта, который должен быть протестирован (хотя из-за * вид * глобальный характер, это может быть не так). –

+0

@jimmy_keen 'Manager' всегда можно было высмеивать, а затем проверять другой код. И если что-то еще «получается», это не сложно реорганизовать. Современные IDE имеют рефакторинг «извлечения интерфейса», что делает изменение тривиальным. – kan

+0

Думаю, я могу жить с помощью суперпоточного метода setMyDao(). Я думал, что должен тестировать интерфейсы, а не конкретные реализации (Менеджер). Наверное, я ошибся, иногда это невозможно. –

1

Вы можете избавиться от set методов в целом и ввести завод. Таким образом, никакой дополнительный метод не отображается (фактически, никакой дополнительный метод даже не существует), и проблема исчезает. Затем в тесте вы настраиваете фабричный макет, чтобы вернуть DAO mocks, и с этого момента он прост и прост.

+0

Неплохо смешивать шаблоны проектирования 'Dependency injection' и' Service Locator'. Это просто усложняет все. – kan

+1

@kan: локатор обслуживания? Смешение анти-шаблона с чем-то, вероятно, плохой идеей; Я говорю об абстрактной фабрике, которая хорошо подходит в сценарии OP и вообще ничего не усложняет. –

+0

Как я понимаю, фабрика, о которой вы говорите, вернет DAO, взяв ее из контейнера. В реальном приложении (я имею в виду не единичные тесты) DAO будут созданы и подключены контейнером. В противном случае, как это будет реализовано? Не забывайте, что DAO также имеют собственные зависимости.Другими словами, это SL, фактически реализованный на заводе. – kan