I want to create some integration tests for the following class:
public class MyDao {
@Inject
@Postgres
private DataSource dataSource;
getSomething() {
//do something with dataSource
}
}
I have the qualifier:
@Qualifier
@Target({ TYPE, METHOD, FIELD, PARAMETER })
@Retention(RUNTIME)
public @interface Postgres {
}
And also I have a producer:
public class PostgresDataSourceProducer {
@Resource(mappedName = "java:jboss/PostgresDS")
private DataSource ds;
@Produces
@Postgres
DataSource postgresDataSouce() {
return ds;
}
}
I'm using wildfly 14. Data source was defined in the 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>
To create integration tests, I will need to change the datasource to point to my test database. How to do that?
Because it'a a legacy code, I'm reserved to switch from @Resource
to @PersistenceContext
.
There are many ways to do this, but first, define your test data-source in the subsystem (let's map it with java:jboss/H2
for the sake of the examples below).
Via the CDI @Alternative
Create another producer class for the test data-source and marked it as an alternative.
Example:
public class PostgresDataSourceProducer {
@Resource(mappedName = "java:jboss/PostgresDS")
private DataSource primary;
}
@Alternative
public class H2DataSourceProducer {
@Resource(mappedName = "java:jboss/H2")
private DataSource test;
}
In the test resource directory, add a new CDI descriptor file specifically for tests. You may want to copy the configs from the main descriptor file to retain behaviors or avoid runtime errors.
Example:
<?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>
And lastly, when creating your test artifacts via Shrinkwrap
, replace the CDI descriptor files for the affected modules with the one above.
Example:
final var services = ...;
services.addAsManifestResource("META-INF/beans.xml", "beans.xml");
Via the JPA Persistence-unit config
You may also just scrape the data-source producer and let JPA get the correct data-source at runtime via the persistence-unit config.
Add a new persistence.xml
file in the test resource directory. Retain everything from the main persistence config except for the data-source property.
Example:
<?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>
And lastly, when creating your test artifacts via Shrinkwrap
, replace the main persistence config file with the one above.