Wednesday, December 16, 2015

Use Spring Test without @RunWith(SpringJUnit4ClassRunner.class)

This is a new feature from Spring framework 4.2. Now you can use other JUnit's runners,like Parameterized or MockitoJUnitRunner but without losing spring test benefits. (with all the features you love with spring-test like spring  Dependency Injection , Auto-rollback Transaction for test and etc).

In this article, a simple hello world level JUnit test case is provided with JUnit Parameterized runner, with spring-test support enabled.

0. What you need

  • JDK 1.7 +
  • Spring framework 4.2 + ( 4.2.1.RELEASE is used in this demo)
  • Maven 3.2+ (This demo is a maven project, but maven is not necessary for enable Spring-test support in other JUnit runners)

1. Define pom.xml

<project xmlns="" 



    <!-- Spring framework -->

    <!-- Spring test -->
    <!-- JUnit test -->

      <!-- Use Java 1.7 -->

The pom specifies 3 dependencies, spring-context, spring-test and junit. Also it specify the Java version to 1.7.

2. Define Java Class

There are 3 classes in this demo. First is, which is a Spring bean as test target. 

package com.shengwang.demo;

import org.springframework.stereotype.Service;

public class HelloService {

  public String sayHello(String name) {
    return "Hello " + name;

The second is, as Spring context configuration.

package com.shengwang.demo;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

public class JavaConfig {}

The Last is the JUnit test case use Parameterized as runner.

package com.shengwang.demo;

import java.util.Arrays;
import java.util.Collection;

import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;

@ContextConfiguration(classes=JavaConfig.class)  // specify context config
public class HelloServiceTest {
  // -------------------------------------------
  //  spring test support requirement from 4.2
  // -------------------------------------------
  public static final SpringClassRule SPRING_CLASS_RULE= new SpringClassRule();
  public final SpringMethodRule  springMethodRule = new SpringMethodRule();
  // -------------------------------------------
  //  spring test support requirement over
  // -------------------------------------------
  private String name;
  HelloService service;

  public HelloServiceTest(String name) { = name;
  public static Collection<String[]> data() {
    return Arrays.asList(new String[][] {
  public void testSayHello() {

The test case enable spring-test support by 3 steps:

  1. 1. Use @ContextConfiguration to config Spring TestContext .
  2. 2. Add a SpringClassRule static variable
  3. 3. Add a SpringMethodRule field variable

The project's hierarchy looks like below:


Now the test get all abilities from spring-test. The @Autowired dependency injection works perfectly.



  1. actually this is just one post with valid information, that is really working... Thank you Sheng!

  2. Thanks a lot. This is working.

  3. java.lang.IllegalStateException: Failed to find 'public SpringMethodRule' field in test class

  4. It works, but only with packages.


Powered by Blogger.

About The Author

My Photo

Has been a senior software developer, project manager for 10+ years. Dedicate himself to Alcatel-Lucent and China Telecom for delivering software solutions.


Unordered List