Reading custom annotation for JUNIT
I have a custom annotation which I use as config to start off one time set-up for Junit.
@Target(TYPE) @Retention(RUNTIME)
public @interface MyAnnotation{
String host();
int port();
}
Test class:
@MyAnnotation(host="0.0.0.0", port=4567)
public class MyTest extends MyAbstractClass{
@Test
public void myTest(){
//do testy things
}
}
Superclass:
public class MyAbstractClass{
@BeforeAll
public static void start(){
Config cfg = readConfig();
//Use config to do one time set-up
}
private static Config readConfig(){
MyAnnotation ann = MyTest.class.getAnnotation(MyAnnotation.class);
return new Config(ann.host(), ann.port());
}
}
So currently, I hardcode the name of the test class (MyTest) in readConfig(..). This won't work when I add a second test class.
One way to solve it is:
- Add another @BeforeAll method in MyTest which will call the @BeforeAll in super-class and pass the class name as a param.
However, I am curious if I can read the name of the executing subclass in the superclass via some reflexion magic. Any ideas are most welcome.
Thanks
The presence of the @BeforeAll
annotation suggests you are using JUnit 5. In this case, you can use.
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.TestInfo;
public class MyAbstractClass {
@BeforeAll
public static void start(TestInfo ti) {
Config cfg=readConfig(ti.getTestClass().orElseThrow(IllegalStateException::new));
//Use config to do one time set-up
}
private static Config readConfig(Class<?> testClass) {
MyAnnotation ann = testClass.getAnnotation(MyAnnotation.class);
return new Config(ann.host(), ann.port());
}
}
See also the TestInfo
API documentation.
This is not “Reflection Magic” but a feature provided by JUnit itself, but it’s also only JUnit which knows that the invocation of a static
method annotated with @BeforeAll
is associated with a particular test class it is going to process.