I need to use extensions to run code before and after all test cases in classes that use it. My test classes need to access a field in my Extension class. Is this possible?
Given:
@ExtendWith(MyExtension.class)
public class MyTestClass {
@Test
public void test() {
// get myField from extension and use it in the test
}
}
and
public class MyExtension implements
BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {
private int myField;
public MyExtension() {
myField = someLogic();
}
...
}
How do I access myField from my test class?
You can achieve this via a marker annotation and a BeforeEachCallback extension.
Create a special marker annotation, e.g.
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyField {
}
Use the annotation to find and set the values from within the extension:
import org.junit.jupiter.api.extension.BeforeEachCallback;
public class MyExtension implements BeforeEachCallback {
@Override
public void beforeEach(final ExtensionContext context) throws Exception {
// Get the list of test instances (instances of test classes)
final List<Object> testInstances =
context.getRequiredTestInstances().getAllInstances();
// Find all fields annotated with @MyField
// in all testInstances objects.
// You may use a utility library of your choice for this task.
// See for example, https://github.com/ronmamo/reflections
// I've omitted this boilerplate code here.
// Assign the annotated field's value via reflection.
// I've omitted this boilerplate code here.
}
}
Then, in your tests, you annotate the target field and extend the test with your extension:
@ExtendWith(MyExtension.class)
public class MyTestClass {
@MyField
int myField;
@Test
public void test() {
// use myField which has been assigned by the extension before test execution
}
}
Note: you can alternatively extend BeforeAllCallback which is executed once before all test methods of the class, depending on your actual requirements.