如何测试用@Resource 注入的数据源
How to test data source injected with @Resource
我想为以下 class 创建一些集成测试:
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;
}
}
我正在使用 wildfly 14。数据源在 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
。
有很多方法可以做到这一点,但首先,在子系统中定义您的测试 data-source(为了下面的示例,我们将其映射为 java:jboss/H2
)。
通过 CDI @Alternative
为测试data-source创建另一个生产者class并将其标记为备选。
示例:
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 Persistence-unit 配置
您也可以 抓取 data-source 生产者并让 JPA 在运行时通过 persistence-unit 配置获得正确的 data-source。
在测试资源目录中添加一个新的persistence.xml
文件。保留主持久性配置中的所有内容,除了 data-source 属性.
示例:
<?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
创建测试工件时,用上面的文件替换主持久性配置文件。
我想为以下 class 创建一些集成测试:
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;
}
}
我正在使用 wildfly 14。数据源在 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
。
有很多方法可以做到这一点,但首先,在子系统中定义您的测试 data-source(为了下面的示例,我们将其映射为 java:jboss/H2
)。
通过 CDI @Alternative
为测试data-source创建另一个生产者class并将其标记为备选。
示例:
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 Persistence-unit 配置
您也可以 抓取 data-source 生产者并让 JPA 在运行时通过 persistence-unit 配置获得正确的 data-source。
在测试资源目录中添加一个新的persistence.xml
文件。保留主持久性配置中的所有内容,除了 data-source 属性.
示例:
<?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
创建测试工件时,用上面的文件替换主持久性配置文件。