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?
Annotation for fields of the test class which will be initialized by the method annotated by Parameters . Annotation for a method which provides parameters to be injected into the test class constructor by Parameterized . Add this annotation to your test class if you want to generate a special runner.
@BeforeEach is used to signal that the annotated method should be executed before each @Test method in the current test class.
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.
Report example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With