I have a situation where I need to be able to run a suite of JUnit tests under 2 different "modes":
@Before and @After annotations/methods are used; but...@Test methodsFor example:
public class WidgetTest {
@Before
void start() {
// Do some start up work.
}
@After
void stop() {
// Do some shutdown work.
}
@Test
public void testWidget() {
// Given/When/Then, etc.
}
}
In "Mode #1", I want @Before and @After methods (start() and stop() respectively) to execute before/after testWidget(). But in "Mode #2", I would only want the testWidget() method to fire.
The best I can come up with is:
public class WidgetTest {
private boolean useHooks;
// Ctor, getter and setter for 'useHooks'.
@Before
void start() {
if(useHooks) {
// Do some start up work.
}
}
@After
void stop() {
if(useHooks) {
// Do some shutdown work.
}
}
@Test
public void testWidget() {
// Given/When/Then, etc.
}
}
But then this presents an additional problem: How do I inject useHooks into my test suite? It is also kind of hacky, and I guess I'm hoping that JUnit supports this kind of use case out of the box.
Is there a way to accomplish this? If so, how?
Check out @Category annotation
I suggest to consider this solution:
Here is the code of the custom runner I've come up with:
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.internal.runners.statements.RunAfters;
import org.junit.internal.runners.statements.RunBefores;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
public class MyJUnitRunner extends BlockJUnit4ClassRunner {
private final boolean runBeforesAndAfters = System.getProperty("run-befores-and-afters") != null;
public MyJUnitRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) {
List<FrameworkMethod> befores = Collections.EMPTY_LIST;
if (runBeforesAndAfters) {
befores = getTestClass().getAnnotatedMethods(Before.class);
}
return befores.isEmpty() ? statement : new RunBefores(statement, befores, target);
}
@Override
protected Statement withAfters(FrameworkMethod method, Object target, Statement statement) {
List<FrameworkMethod> afters = Collections.EMPTY_LIST;
if (runBeforesAndAfters) {
afters = getTestClass().getAnnotatedMethods(After.class);
}
return afters.isEmpty() ? statement : new RunAfters(statement, afters, target);
}
}
All you have to do it start the JUnits VM with this option added: -Drun-befores-and-afters and annotate your test class with @RunWith(MyJUnitRunner.class) and then you are done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With