62780

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

Question:

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

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

<ol><li><strong>@RunWith</strong> (my test may, or may not use this annotation already, so I cannot assume that I will be able to use my own runner)</li> <li><strong>AOP</strong> (I cannot make any dependencies to third party libraries, such as AspectJ)</li> </ol>

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?

Answer1:

You need a solution very similar to the answer to <a href="https://stackoverflow.com/questions/4055022/mark-unit-test-as-an-expected-failure-in-junit/8092927#8092927" rel="nofollow">Mark unit test as an expected failure</a>, based upon a <a href="http://kentbeck.github.com/junit/javadoc/latest/org/junit/rules/TestRule.html" rel="nofollow">TestRule</a>. 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 } }

Answer2:

I would split the class into two. One with the methods you would have annotated with @mine and one for the others.

Then use @before as normal.

This adds no none standard code and will be easy to understand and maintain for future developers as well.

Recommend

  • AspectJ: Intercept method execution/call and make it return
  • Can aspectj add methods to java.lang.String
  • Get the value of the accessed field within a get pointcut
  • Run a method before and after a called method in Java
  • Displaying 'Please fill out this field' for all empty and required fields
  • How to write an annotation/aspect to not enter a method but return null if a given condition is fals
  • Updated Spring 3.1 project to hibernate4 now getting No Session found for current thread
  • Is there a Spring AOP annotation which lets us go inside a method only if that annotation returns tr
  • Aspectj for anotations with classes not working
  • Disable Thread.sleep()
  • How to run some code before each JUnit @Test method individually, without using @RunWith nor AOP?
  • Spring boot jar fails to start embedded server on adding tomcat-embed-jasper dependency
  • Spring AOP with Around advice and @annotation not working
  • How to configure aspectj ignore getters and setters
  • @AspectJ pointcut for execute methods of a package
  • org.aspectj.lang.NoAspectBoundException - method ()V not found
  • Spring Boot Ambiguous mapping. Cannot map method
  • no longer possible in Spring 3.1
  • Spring AOP :- Getting parameterNames as null in the joinPoint
  • vim buffer Trying char-by-char conversion
  • Setting jsp checkbox with a value from database
  • Jquery autocomplete with php as remote source: how to append second variable from input to source
  • Is there a common practice to track the user session across browser window?
  • how to set variables in a php include file?
  • How to determine if there are bytes available to be read from boost:asio:serial_port
  • Unity3D & Android: Difference between “UnityMain” and “main” threads?
  • Recording logins for password protected directories
  • Spray.io: When (not) to use non-blocking route handling?
  • Check if a string to interpolate provides expected placeholders
  • RestKit - RKRequestDelegate does not exist
  • Hibernate gives error error as “Access to DialectResolutionInfo cannot be null when 'hibernate.
  • Traverse Array and Display in markup
  • PHP: When would you need the self:: keyword?
  • Acquiring multiple attributes from .xml file in c#
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • python draw pie shapes with colour filled
  • Is there any way to bind data to data.frame by some index?
  • reshape alternating columns in less time and using less memory
  • How can i traverse a binary tree from right to left in java?
  • How can I use threading to 'tick' a timer to be accessed by other threads?