I have a class that is a JUnit suite of JUnit test classes. I would like to define a rule on the suite to do something to the database before and after each unit test is run if a certain annotation is present on that test method.
I've been able to create a @ClassRule
in the suites and test classes that will do this before each and every class (which is not good enough) and I have been able to define the test rules with the test classes themselves, but this is repetitive and does not seem very DRY.
Is it possible to define a per-test-method rule in the suite or must I add them to each and every test?
Edit: To clarify, I want to declare code in a suite that will run between (i.e. "around") the test methods in the test classes.
Best Answer
This can be done, but it needs a bit of work. You need to define your own Suite runner and your own Test runner as well, and then override runChild() in the test runner. Using the following:
AllTests.java:
Class1Test.java:
Note that I've annotated
test1()
with@Deprecated
. You want to do something different when you have the@Deprecated
annotation on the test, so we need to extend Suite to use a customRunner
:JUnit creates a
Runner
for each test it will run. Normally, Suite would just create the defaultBlockJUnit4ClassRunner
, all we're doing here is overriding the constructor for the Suite which reads the classes from theSuiteClass
annotation and we're creating our own runners with them,MyRunner
. This is our MyRunner class:Most of this is copied from
BlockJUnit4ClassRunner
. The bit I've added is:where we test for the existence of the
@Deprecated
annotation on the method, and do something if it's there. The rest is left as an exercise for the reader. When I run the above Suite, I get as output:Please note that Suite has multiple constructors depending upon how it is invoked. The above works with Eclipse, but I haven't tested other ways of running the Suite. See the comments alongside the various constructors for Suite for more information.