Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run some code before each JUnit @Test method individually, without using @RunWith nor AOP?

use case is simple: I want to run some boiler plate code before each method in JUnit test annotated with @Test and my custom annotation (let's call it @Mine).

I do not want to use following methods (explanation in parenthesis):

  1. @RunWith (my test may, or may not use this annotation already, so I cannot assume that I will be able to use my own runner)
  2. AOP (I cannot make any dependencies to third party libraries, such as AspectJ)

I guess this leaves me with reflection only, which is fine by me. I thought off using @Before accompanied with getting current method via Thread.getCurrentThread() etc. but somehow I find this solution to be a little bit dirty, since I would have to make boiler plate code again within this method to fire reflection (and avoiding any unnecessary code was the goal in the first place).

Maybe you have some other ideas?

like image 722
ŁukaszBachman Avatar asked Dec 09 '22 04:12

ŁukaszBachman


1 Answers

You need a solution very similar to the answer to Mark unit test as an expected failure, based upon a TestRule. Using the example of a @Deprecated annotation (you can use yours here), you can insert code if the annotation exists on the method. The Description class contains the list of annotations on the method.

public class ExecutionTest {
    public class BeforeExecution implements TestRule {
        public Statement apply(Statement base, Description description) {
            return statement(base, description);
        }

        private Statement statement(final Statement base, final Description description) {
            return new Statement() {
                @Override
                public void evaluate() throws Throwable {
                    if (description.getAnnotation(Deprecated.class) != null) {
                        // you can do whatever you like here.
                        System.err.println("this will be run when the method has an @Deprecated annotation");
                    }
                    base.evaluate();
                }
            };
        }
    }

    @Rule public BeforeExecution beforeExecution = new BeforeExecution();

    // Will have code executed.
    @Deprecated
    @Test public void test1() {
         // stuff
    }

    // won't have code executed.
    @Test public void test2() {
         // stuff
    }
}
like image 106
Matthew Farwell Avatar answered Dec 11 '22 16:12

Matthew Farwell