Pet*_*ker 67 java testing integration-testing maven-2 jpa
有没有办法在Maven项目中设置第二个persistence.xml文件,以便用于测试而不是用于部署的普通文件?
我尝试将一个persistence.xml放入src/test/resources/META-INF,它被复制到target/test-classes/META-INF中,但似乎是target/classes/META-INF(来自src/main的副本)尽管mvn -X test以正确的顺序列出了类路径条目,但首选资源是首选的:
[DEBUG] Test Classpath :
[DEBUG] /home/uqpbecke/dev/NetBeansProjects/UserManager/target/test-classes
[DEBUG] /home/uqpbecke/dev/NetBeansProjects/UserManager/target/classes
[DEBUG] /home/uqpbecke/.m2/repository/junit/junit/4.5/junit-4.5.jar
...
Run Code Online (Sandbox Code Playgroud)
我希望能够针对简单的hsqldb配置运行测试,而无需更改JPA配置的部署版本,理想情况是在项目结账后直接进行,无需进行本地调整.
Ric*_*ler 26
以下内容适用于Maven 2.1+(在此之前,测试和包之间没有可以绑定执行的阶段).
您可以使用maven-antrun-plugin在测试期间将persistence.xml替换为测试版本,然后在打包项目之前恢复正确的版本.
此示例假定生产版本为src/main/resources/META-INF/persistence.xml,测试版本为src/test/resources/META-INF/persistence.xml,因此它们将被复制到target/classes/META -INF和target/test-classes/META-INF分别.
将它封装成mojo会更优雅,但是因为你只是复制一个文件,所以看起来有点过分.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>copy-test-persistence</id>
<phase>process-test-resources</phase>
<configuration>
<tasks>
<!--backup the "proper" persistence.xml-->
<copy file="${project.build.outputDirectory}/META-INF/persistence.xml" tofile="${project.build.outputDirectory}/META-INF/persistence.xml.proper"/>
<!--replace the "proper" persistence.xml with the "test" version-->
<copy file="${project.build.testOutputDirectory}/META-INF/persistence.xml" tofile="${project.build.outputDirectory}/META-INF/persistence.xml"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>restore-persistence</id>
<phase>prepare-package</phase>
<configuration>
<tasks>
<!--restore the "proper" persistence.xml-->
<copy file="${project.build.outputDirectory}/META-INF/persistence.xml.proper" tofile="${project.build.outputDirectory}/META-INF/persistence.xml"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
Arj*_*jan 21
在EE6/CDI/JPA项目中,src/test/resources/META-INF/persistence.xml无需进一步配置即可完成测试.
在Spring中使用JPA时,以下工作在用于测试的应用程序上下文中:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--
JPA requires META-INF/persistence.xml, but somehow prefers the one
in classes/META-INF over the one in test-classes/META-INF. Spring
to the rescue, as it allows for setting things differently, like by
referring to "classpath:persistence-TEST.xml". Or, simply referring
to "META-INF/persistence.xml" makes JPA use the test version too:
-->
<property name="persistenceXmlLocation" value="META-INF/persistence.xml" />
<!-- As defined in /src/test/resources/META-INF/persistence.xml -->
<property name="persistenceUnitName" value="myTestPersistenceUnit" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
</bean>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
在这里,/src/test/resources/META-INF/persistence.xml(复制到target/test-classes)将优先于/src/main/resources/META-INF/persistence.xml(复制到target/classes).
Unfortunately, the location of the persistence.xml file also determines the so-called "persistence unit's root", which then determines which classes are scanned for @Entity annotations. So, using /src/test/resources/META-INF/persistence.xml would scan classes in target/test-classes, not classes in target/classes (where the classes that need to be tested would live).
Hence, for testing, one would need to explicitly add <class> entries to persistence.xml, to avoid java.lang.IllegalArgumentException: Not an entity: class .... The need for <class> entries can be avoided by using a different file name, like persistence-TEST.xml, and put that file in the very same folder as the regular persistence.xml file. The Spring context from your test folder can then just refer to <property name="persistenceXmlLocation" value="META-INF/persistence-TEST.xml" />, and Spring will find it for you in src/main.
作为替代方案,可以persistence.xml为实际应用程序和测试保持相同,并且仅定义一个src/main.大多数配置(如驱动程序,方言和可选凭据)都可以在Spring上下文中完成.还hibernate.hbm2ddl.auto可以在上下文中传递设置:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- For example: com.mysql.jdbc.Driver or org.h2.Driver -->
<property name="driverClassName" value="#{myConfig['db.driver']}" />
<!-- For example: jdbc:mysql://localhost:3306/myDbName or
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 -->
<property name="url" value="#{myConfig['db.url']}" />
<!-- Ignored for H2 -->
<property name="username" value="#{myConfig['db.username']}" />
<property name="password" value="#{myConfig['db.password']}" />
</bean>
<bean id="jpaAdaptor"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- For example: org.hibernate.dialect.MySQL5Dialect or
org.hibernate.dialect.H2Dialect -->
<property name="databasePlatform" value="#{myConfig['db.dialect']}" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="jpaProperties">
<props>
<!-- For example: validate, update, create or create-drop -->
<prop key="hibernate.hbm2ddl.auto">#{myConfig['db.ddl']}</prop>
<prop key="hibernate.show_sql">#{myConfig['db.showSql']}</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
Pet*_*ker 13
似乎多个persistence.xml文件是JPA的一般问题,只能通过类加载技巧来解决.
对我有用的解决方法是在一个persistence.xml文件中定义多个持久性单元,然后确保您的部署和测试代码使用不同的绑定(在Spring中,您可以在实体管理器工厂中设置"persistenceUnitName"属性).它会使用测试配置污染您的部署文件,但如果您不介意它可以正常工作.
为测试添加一个persistance.xml:/src/test/resources/META-INF/persistence.xml
正如@Arjan所说,这将改变持久性单元的根,实体类将在目标/测试类中进行扫描.要处理它,请将jar-file元素添加到此persistance.xml:
/src/test/resources/META-INF/persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="com.some.project">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jar-file>${project.basedir}/target/classes</jar-file>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/test_database" />
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="..." />
</properties>
</persistence-unit>
</persistence>
Run Code Online (Sandbox Code Playgroud)
然后,将测试资源的过滤添加到pom.xml:
<project>
...
<build>
...
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
...
</build>
...
</project>
Run Code Online (Sandbox Code Playgroud)
这将起作用,因为jar文件可以定位到目录,而不仅仅是jar文件.
小智 6
我尝试了ClassLoaderProxy方法但遇到的问题是,JPA带注释的类不会被hibernate作为持久化类处理.
所以决定不使用persistence.xml就试一试.优点是maven构建和Eclipse JUnit测试无需修改即可运行.
我有一个用于JUnit测试的persitent支持类.
public class PersistenceTestSupport {
protected EntityManager em;
protected EntityTransaction et;
/**
* Setup the the {@code EntityManager} and {@code EntityTransaction} for
* local junit testing.
*/
public void setup() {
Properties props = new Properties();
props.put("hibernate.hbm2ddl.auto", "create-drop");
props.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
props.put("hibernate.connection.url", "jdbc:mysql://localhost/db_name");
props.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
props.put("hibernate.connection.username", "user");
props.put("hibernate.connection.password", "****");
Ejb3Configuration cfg = new Ejb3Configuration();
em = cfg.addProperties(props)
.addAnnotatedClass(Class1.class)
.addAnnotatedClass(Class2.class)
...
.addAnnotatedClass(Classn.class)
.buildEntityManagerFactory()
.createEntityManager();
et = em.getTransaction();
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试类只是扩展PersistenceTestSupport并调用TestCase.setup()中的setup().
唯一的缺点是保持持久化的类,但对于JUnit测试,这对我来说是可以接受的.
小智 5
我更喜欢使用不同的persistence.xml作为Rich Seller 帖子进行测试和制作的解决方案(谢谢!!).
但需要改变:
<copy file="${project.build.outputDirectory}/META-INF/persistence.xml.proper" tofile="${project.build.outputDirectory}/META-INF/persistence.xml"/>
Run Code Online (Sandbox Code Playgroud)
对于:
<move file="${project.build.outputDirectory}/META-INF/persistence.xml.proper" tofile="${project.build.outputDirectory}/META-INF/persistence.xml" overwrite="true"/>
Run Code Online (Sandbox Code Playgroud)
为了使persistence.xml.proper不嵌入.jar文件中
保留 persistence.xml 文件的两个副本。一个用于测试,另一个用于正常构建。
默认生命周期将构建的 persistence.xml 复制到 src/test/resources/META-INF
创建一个单独的配置文件,运行时会将测试 persistence.xml 复制到 src/test/resources/META-INF
| 归档时间: |
|
| 查看次数: |
54685 次 |
| 最近记录: |