Подтвердить что ты не робот

Лучшие практики JUnit Test на основе JPA

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

Добавление: могут ли другие тестовые рамки (например, TestNG) сделать это проще?

4b9b3361

Ответ 1

Вы можете попробовать mockito. Тест работает следующим образом:

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

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

И как отметил топчеф, тестирование на основе транзакций отлично.

Ответ 4

Как уже упоминалось здесь: 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"/>