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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 < modelVersion >4.0.0</ modelVersion > < groupId >com.shengwang.demo</ groupId > < artifactId >spring-test-simple</ artifactId > < version >1</ version > < packaging >jar</ packaging > < name >spring-test-simple</ name > < dependencies > <!-- Spring framework --> < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-context</ artifactId > < version >4.2.1.RELEASE</ version > </ dependency > <!-- Spring test --> < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-test</ artifactId > < version >4.2.1.RELEASE</ version > < scope >test</ scope > </ dependency > <!-- JUnit test --> < dependency > < groupId >junit</ groupId > < artifactId >junit</ artifactId > < version >4.11</ version > < scope >test</ scope > </ dependency > </ dependencies > < build > < plugins > <!-- Use Java 1.7 --> < plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-compiler-plugin</ artifactId > < version >2.5.1</ version > < configuration > < source >1.7</ source > < target >1.7</ target > </ configuration > </ plugin > </ plugins > </ build > </ project > |
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 HelloService.java, which is a Spring bean as test target.
1 2 3 4 5 6 7 8 9 10 11 | package com.shengwang.demo; import org.springframework.stereotype.Service; @Service public class HelloService { public String sayHello(String name) { return "Hello " + name; } } |
The second is JavaConfig.java, as Spring context configuration.
1 2 3 4 5 6 7 8 | package com.shengwang.demo; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan public class JavaConfig {} |
The Last is the JUnit test case HelloServiceTest.java use Parameterized as runner.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 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; @RunWith (Parameterized. class ) @ContextConfiguration (classes=JavaConfig. class ) // specify context config public class HelloServiceTest { // ------------------------------------------- // spring test support requirement from 4.2 // ------------------------------------------- @ClassRule public static final SpringClassRule SPRING_CLASS_RULE= new SpringClassRule(); @Rule public final SpringMethodRule springMethodRule = new SpringMethodRule(); // ------------------------------------------- // spring test support requirement over // ------------------------------------------- private String name; @Autowired HelloService service; public HelloServiceTest(String name) { this .name = name; } @Parameters public static Collection<String[]> data() { return Arrays.asList( new String[][] { { "Tom" },{ "Jerry" } }); } @Test public void testSayHello() { service.sayHello(name); } } |
The test case enable spring-test support by 3 steps:
- 1. Use @ContextConfiguration to config Spring TestContext .
- 2. Add a SpringClassRule static variable
- 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.
actually this is just one post with valid information, that is really working... Thank you Sheng!
ReplyDeleteThanks a lot. This is working.
ReplyDeletejava.lang.IllegalStateException: Failed to find 'public SpringMethodRule' field in test class
ReplyDeleteIt works, but only with packages.
ReplyDeletehttps://stackoverflow.com/questions/37927451/migration-spring-project-from-tomcat-7-to-tomcat-8/44463471#44463471