问题描述
我想为以下课程创建一些集成测试:
public class MyDao {
@Inject
@Postgres
private DataSource dataSource;
getSomething() {
//do something with dataSource
}
}
我有资格赛:
@Qualifier
@Target({ TYPE,METHOD,FIELD,ParaMETER })
@Retention(RUNTIME)
public @interface Postgres {
}
还有一个制片人:
public class PostgresDataSourceProducer {
@Resource(mappedname = "java:jboss/PostgresDS")
private DataSource ds;
@Produces
@Postgres
DataSource postgresDataSouce() {
return ds;
}
}
我正在使用wildfly14。数据源是在standalone.xml中定义的:
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<datasources>
<datasource jta="false" jndi-name="java:jboss/PostgresDS" pool-name="postgres" enabled="true" use-ccm="false">
<connection-url>jdbc:postgresql://${production.postgres.url}</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<driver>postgresql-8.0-310.jdbc3.jar</driver>
<security>
<user-name>${db.username}</user-name>
<password>${db.userpass}</password>
</security>
<validation>
<validate-on-match>false</validate-on-match>
<background-validation>false</background-validation>
</validation>
<statement>
<share-prepared-statements>false</share-prepared-statements>
</statement>
</datasource>
</datasources>
</subsystem>
要创建集成测试,我将需要更改数据源以指向我的测试数据库。该怎么做?
由于这是一个旧代码,我保留从@Resource
切换到@PersistenceContext
的权限。
解决方法
有许多方法可以做到这一点,但首先,在子系统中定义测试数据源(为便于使用,请在下面的示例中使用java:jboss/H2
对其进行映射)。
通过CDI @Alternative
为测试数据源创建另一个生产者类,并将其标记为替代类。
示例:
public class PostgresDataSourceProducer {
@Resource(mappedName = "java:jboss/PostgresDS")
private DataSource primary;
}
@Alternative
public class H2DataSourceProducer {
@Resource(mappedName = "java:jboss/H2")
private DataSource test;
}
在测试资源目录中,添加一个专门用于测试的新CDI描述符文件。您可能需要从主描述符文件中复制配置,以保留行为或避免运行时错误。
示例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
<alternatives>
<class>path.to.your.datasource.H2DataSourceProducer</class>
</alternatives>
</beans>
最后,当通过Shrinkwrap
创建测试工件时,将受影响的模块的CDI描述符文件替换为上面的模块。
示例:
final var services = ...;
services.addAsManifestResource("META-INF/beans.xml","beans.xml");
通过JPA持久性单元配置
您还可以只删除数据源生产者,并让JPA在运行时通过持久性单元配置获取正确的数据源。
在测试资源目录中添加新的persistence.xml
文件。保留除数据源属性以外的所有主要持久性配置。
示例:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name="primary">
<!--<jta-data-source>java:jboss/PostgresDS</jta-data-source>-->
<jta-data-source>java:jboss/H2</jta-data-source>
...
</persistence-unit>
</persistence>
最后,当通过Shrinkwrap
创建测试工件时,将主持久性配置文件替换为上面的文件。