I have a number of test cases in JUnit. All of them need the same code to be executed in their @BeforeClass
static method. It's a code duplication and I'm trying to get rid of it. A dirty way of doing this is by inheritance. Are there any other mechanisms in JUnit, that may help?
PS. I wrote this blog post about this very subject: http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html
Inheritance creates dependency between child and parent, when a class inherit another class, we include all methods and attributes from parent class and expose to the child class, therefore we break the encapsulation, the child object can access all the methods in parent object and overwrite them.
The JUnit TestRunners will catch the thrown Exception regardless so you don't have to worry about your entire test suite bailing out if an Exception is thrown. This is the best answer.
If you want to ignore a test method, use @Ignore along with @Test annotation. If you want to ignore all the tests of class, use @Ignore annotation at the class level.
A test method annotated with @Ignore will not be executed. If a test class is annotated with @Ignore, then none of its test methods will be executed.
The JUnit way to compose reusable code (instead of inheriting from it) are Rules.
See https://github.com/junit-team/junit/wiki/Rules
Here is a dumb sample, but you'll get the point.
import org.junit.rules.TestRule; import org.junit.runners.model.Statement; import org.junit.runner.Description; public class MyTestRule implements TestRule { @Override public Statement apply(final Statement statement, Description description) { return new Statement() { public void evaluate() throws Throwable { // Here is BEFORE_CODE try { statement.evaluate(); } finally { // Here is AFTER_CODE } } }; } }
You can then use your TestRule like this:
import org.junit.Rule; public class MyTest { @Rule public MyTestRule myRule = new MyTestRule(); }
BEFORE_CODE and AFTER_CODE will then be executed around each of your test methods.
If you need to run your code only once per class, use your TestRule as a @ClassRule:
import org.junit.ClassRule; public class MyTest { @ClassRule public static MyTestRule myRule = new MyTestRule(); }
Now, BEFORE_CODE
and AFTER_CODE
will be executed around each of your test class.
@Rule field is not static, @ClassRule field is.
A @ClassRule can be declared in a Suite too.
Note that you can declare several rules in a single test class, that's how you compose test lifecycles at test-suites, test-classes and test-methods levels.
A Rule is an object that you instanciate in your test classes (statically or not). You can add contructor parameters if needed.
HTH
If the method is some kind of utility, then separate it out to a different class with a static method and call that method in your @BeforeClass.
I emphasize on the fact that don't use inheritance just because it solves your problem, use it when doing so creates sense in your class hierarchy.
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