@RunWith in junit4
@RunWith is used to specify the Runner
to run the unit test. A runner defines how a test method executes usually through reflection mechanism. The default runner in junit4 is BlockJUnit4ClassRunner
.
Above image is clipped from the source code of block runner. It’s easy to figure out that why @Ignore annotation can skip a test method.
Runner is an extension point that we can customize how a test function runs. For example, I want to add a @DisplayName annotation to make the test name more meaningful. I can do it as below:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.runner.Description;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
public class CustomizeTestNameRunner extends BlockJUnit4ClassRunner {
public CustomizeTestNameRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected Description describeChild(FrameworkMethod method) {
DisplayName name = method.getAnnotation(DisplayName.class);
if (name != null) {
return Description.createTestDescription(getTestClass().getJavaClass(), name.value());
}
return super.describeChild(method);
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DisplayName {
String value();
}
}
public class AppTest {
public static int add(int a, int b) {
return a + b;
}
@Test
@DisplayName("test add two integer")
public void testAdd() {
assertEquals(7, add(3, 4));
}
}
Next time if you see a test is annotated with @RunWith(SomeClass.class). Don’t be surprised. The extra features you don’t see before are fully implemented by the Runner.