Imagine this scenario. I need to write a bunch of test methods that all require the same slow and complex set-up. I need to ensure that:
- Every test method tests only one thing. If I have a myriad of unrelated assertions in one test method, and the test fails, it won't be immediately clear what exactly went wrong (and the test method will be huge, compromising readability and maintainability)
- Given N is the number of tests that share the set-up, the set-up is not performed N times (because it's slow and tests should be fast). Simply extracting the set-up code or including a
@BeforeEachmethod is not an option. - Not all test methods are set up the same way. Some may require a fast and simple set-up, others may require a different slow and complex set-up. However, all test methods test the behavior of one class so splitting it into multiple test classes doesn't feel right
public class SomeTest {
@Test
public void testOneThing() {
// slow and complex set-up
// assert(s)
}
@Test
public void testAnotherThing() {
// slow and complex set-up
// other assert(s)
}
// more tests with the shared set-up
}
A chat bot suggested this interesting idea:
public class SomeTest {
@BeforeEach
public void expensiveSetup() {
// Perform slow and complex setup here
}
@ParameterizedTest
@MethodSource("testMethods")
public void runTest(Runnable testMethod) {
testMethod.run();
}
// Define the test methods as static factory methods returning Runnable
private static Stream<Runnable> testMethods() {
return Stream.of(
SomeTest::testOneThing,
SomeTest::testAnotherThing
// Add more test methods here
);
}
// Individual test methods with assertions
private static void testOneThing() {
// Perform assertions for one thing
}
private static void testAnotherThing() {
// Perform assertions for another thing
}
}
However, the drawback is that I wouldn't immediately know which assertion runnable failed if something goes wrong, only its index. Replacing lambdas with anonymous classes that override toString() would be awkward
What can I do in Junit 5 to meet my criteria?