Лучшие практики JUnit на основе JPA - PullRequest
30 голосов
/ 05 августа 2009

Это немного странный вопрос, но он беспокоит меня уже несколько месяцев. Я создал веб-приложение на основе JPA, используя Wicket + Hibernate (созданный с Maven), и хочу напрямую протестировать слой DAO. Я создал специальный файл src / test / resources / META-INF / persistence.xml, который использовал для тестирования, но столкнулся с конфликтами с WTP и тому подобным. Чтобы обойти эти проблемы, я создал отдельный тестовый проект, где живут модульные тесты. Есть ли лучший способ управления модульными тестами для проекта JPA без дуэлей между файлами персистентности?

Приложение: Могут ли это облегчить другие тестовые среды (например, TestNG)?

Ответы [ 4 ]

16 голосов
/ 05 августа 2009

Вы можете попробовать mockito . Тест работает так:

Вы используете mockito для «реализации» EntityManager. Вместо реального кода вы используете методы mockito, чтобы сказать «если приложение вызывает getReference(), то вернуть этот объект». В фоновом режиме mockito создаст экземпляр прокси, который перехватывает вызовы метода Java и возвращает указанные вами значения. Вызовы других методов вернут null.

Насмешливые вещи типа createQuery() работают так же, но сначала вам нужно создать макет Query, а затем использовать тот же подход, что и в getReference() (вернуть макет запроса).

Поскольку вы не используете настоящий EM, вам не нужен настоящий persistence.xml.

Гораздо более простым решением было бы, если бы вы могли установить какое-либо свойство для изменения имени файла persistence.xml, но я не думаю, что это возможно.

Некоторые другие ссылки, которые могут помочь:

5 голосов
/ 06 августа 2009

Мы используем двойные persistence.xml файлы для рабочих и тестовых сред, но это проблема, связанная только с classpath (мы используем Eclipse, но не сильно используем плагины WTP). Единственное различие между ними заключается в том, что рабочая версия не содержит определений сущностей.

Мы не используем фальшивый фреймворк для тестирования JPA, так как это не добавит никакой ценности нашим тестам. Тесты запускают реальный доступ к данным с помощью JPA, который взаимодействует с базой данных PostgreSQL.

Наш подход к тестированию основан на тестовой среде Spring для персистентного уровня: тестирование в транзакции. Наше приложение основано на Spring, но этот подход одинаково применим для произвольных приложений, которые хотят использовать преимущества тестовых классов Spring. Суть в том, что каждый тест выполняется в рамках одной транзакции, которая никогда не фиксируется, и в конце (в tearDown) он автоматически откатывается. Это решает проблему загрязнения данных и проверки зависимости очень приятным, ненавязчивым и прозрачным способом.

Среда тестирования Spring является гибкой и позволяет проводить многозадачное тестирование, но это особые случаи, которые составляют не более 10% тестов.

Мы по-прежнему используем устаревшую поддержку для JUnit 3.8 , но новая Spring TestContext Framework для JUnit 4 выглядит очень привлекательно.

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

Spring DI помогает сделать тесты краткими и информативными, но это не критично.

4 голосов
/ 06 августа 2009

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

И, как указал topchef, модульное тестирование Spring на основе транзакций великолепно.

0 голосов
/ 16 декабря 2011

Как упомянуто здесь: http://www.devx.com/java/Article/36785/1954, вы можете удалить следующие строки из .settings/org.eclipse.wst.common.component вашего проекта, чтобы избежать развертывания тестовых ресурсов в веб-приложении.

<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/resources"/>
...