Reputation: 8075
I want to write a test for a small database-like application. This application uses queries and a query should return the correct result. This is easily implemented in JUnit 5, something like
@BeforeEach
void before() {
database = prepareDatabase();
}
@Test
void testQuery1() {
assertThat(database.query("query1")).isEqualTo("result1");
}
@Test
void testQuery2() {
assertThat(database.query("query2")).isEqualTo("result2");
}
....
Now I want to add optimization switches (e.g. a query optimizer or database indices). The query should return the same results regardless of the running optimization switch (optimizations should only change efficiency not results).
For the test this means that I want to run the same methods for slightly other implementations of prepareDatabase()
(e.g. one with optimizer, one with index, one with nothing).
I did not yet find a proper extension for this. I thought of duplicating the whole class for each optimization setting or providing the methods from a shared parent class. Yet this does not feel like the JUnit 5 way of doing this task. Maybe someone could point me to a feature that could help me with this problem?
Upvotes: 9
Views: 6197
Reputation: 8075
The missing JUnit5 feature is called "Container Templates" and is a scheduled feature request at https://github.com/junit-team/junit5/issues/871.
Upvotes: 3
Reputation: 47
As always, there is multiple possible ways of achieving your goal. One of them is to use Java inheritance. You don't even need to wire up any advanced JUnit 5 feature, just an old Java concepts.
Create abstract class with your methods and abstract prepareDatabase().
public abstract class QueryTest {
Database database;
@BeforeEach
void before() {
database = prepareDatabase();
}
@Test
void testQuery1() {
assertThat(database.query("query1"), is("result1"));
}
@Test
void testQuery2() {
assertThat(database.query("query2"), is("result2"));
}
abstract Database prepareDatabase();
}
Then - based on different variants, create implementations, overriding only this methods.
public class SwitchTrueQueryTest extends QueryTest {
@Override
Database prepareDatabase() {
return new Database(true);
}
}
public class SwitchFalseQueryTest extends QueryTest {
@Override
Database prepareDatabase() {
return new Database(false);
}
}
That's it. Nothing more is necessary, reusable tests are in parent class, no need to duplicate.
Upvotes: 3