Reputation: 20196
We have many test classes that are annotated with @Before and @After to perform test construction/destruction.
But because we now need to perform actions on test failure but prior to @After executing we have used a RuleChain to handle test construction / destruction ourselves. It just points back to the setUp() and tearDown() methods (yes we were lucky that most developers had stuck to that convention).
The problem is that JUnit still invokes the methods annotated with @Before and @After as well as invoking them via the new Rule.
At it's core JUnit is invoking
org.junit.internal.runners.statements.RunAfters.evaluate
for the innermost statement.
One option is obviously removing the @Before and @After annotations from the Tests, but we are talking about many hundreds of tests.
How can we switch off processing of @Before and @After ?
Upvotes: 0
Views: 2425
Reputation: 47865
I don't think you can flick a JUnit 'switch' to disable this behaviour. JUnit offers two ways of changing test execution behaviour:
BlockJUnit4ClassRunner
Rule
to your test caseBoth of these require you to change your test cases, of these the second option might be least invasive (though that does depend on whether your test cases are already using customised runners).
Given this simple JUnit runner:
public class IgnoreBeforeAndAfter extends BlockJUnit4ClassRunner {
public IgnoreBeforeAndAfter(Class<?> klass) throws InitializationError {
super(klass);
}
protected Statement withBefores(FrameworkMethod method, Object target,
Statement statement) {
return statement;
}
protected Statement withAfters(FrameworkMethod method, Object target,
Statement statement) {
return statement;
}
}
The following test case will pass (thereby proving that the @Before
and @After
methods are not invoked):
@RunWith(IgnoreBeforeAndAfter.class)
public class SimpleTest {
@Before
public void setUp() {
Assert.fail("The @Before method should be ignored!");
}
@After
public void tearDown() {
Assert.fail("The @After method should be ignored!");
}
@Test
public void canIgnoreBeforeAndAfter() {
assertTrue(true);
}
}
A structural search+replace on your code base could be used to add this annotation to all test cases which contain at least one of @Before
or @After
.
Though of course a structural search+replace could also remove all @Before
and @After
annotations from your code.
An approach which requires no changes to your existing test cases (but which is somewhat non standard) would be to provide no-op implementations of ...
org.junit.internal.runners.statements.RunAfters
org.junit.internal.runners.statements.RunBefores
... in your own code base, these would 'replace' the JUnit equivalents and if their evaluate()
method body was empty then your use of the @Before
and @After
annotations would have no effect.
Upvotes: 1