Skip to content

JUnit-@RunWith: SpringJUnit4ClassRunner vs. Parameterized

by on August 28, 2014

If you like Spring but you also like data-driven-testing (DDT) you will soon run into a problem: both approaches require to define a runner with @RunWith – but JUnit only allows one runner for one test class.

A blog post by Konrad ‘ktoso’ Malawski actually points to a very interesting approach which is to copy the test-initialization behavior of the SpringJUnit4ClassRunner: @RunWith JUnit4 with BOTH SpringJUnit4ClassRunner and Parameterized.

The solution provided by Konrad uses @Before to set up the TestContextManager which is also used by SpringJUnit4ClassRunner. He actually misses to also respect the other life cycle phases of a test:

  • before test class
  • before test method
  • after test method
  • after test class

To solve these issues you can extend calls to the TestContextManager to @BeforeClass, @AfterClass and @After. But to have a reusable pattern we placed the solution into a JUnit Rule. Because it needs to run in test class and test method mode there is a slight quirk: You have to use the rule as @ClassRule as well as @Rule.

Usage in test:

@ClassRule
public static final SpringAware SPRING_AWARE = 
    SpringAware.forClass(SpringAwareTest.class);
@Rule
public TestRule springAwareMethod =
    SPRING_AWARE.forInstance(this);

Having this you can configure your test nearly just as if you have a SpringJUnit4Runner (with ContextConfiguration and such) despite some exceptions. The following annotations are not interpreted:

There might be more differences – just as always with any copy & paste approach.

Find the rule and a small example test as GitHub Repository.

From → Dev, Testing

2 Comments
  1. Ok but how to use parameterized ? For example I would like to have a constructor with some parameters in my test class … Thx

    • Thanks for your hint that the implementation actually just did not work with the Parameterized runner. The exception you will get trying this solution is a NoSuchMethodException. Thus the constructor is called and initialized as expected but resolving the methods does not work.

      Reason is that the Parameterized runner augments the test method name by the parameters it got called with. I changed the SpringAware implementation to clean up the method name accordingly. A new test (SpringAwareParameterizedTest) shows as example that it works now.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s