如何测试用@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 创建测试工件时,用上面的文件替换主持久性配置文件。