Configuring Spring MVC Test Framework
After we have finished this lesson, we understand how we can configure the Spring MVC Test framework when we are writing integration tests for a “normal” Spring web application or for a web application that uses Spring Boot.
This lesson assumes that:
Writing Integration Tests for a Spring Web Application
If we are writing integration tests for a Spring web application, we can configure the Spring MVC Test framework by following these steps:
First, we have to ensure that the ApplicationContext loaded for our integration test is an instance of the WebApplicationContext class. We can do this by annotating our test class with the @WebAppConfiguration annotation.
After we have annotated our test class with the @WebAppConfiguration annotation, its source code looks as follows:
1import com.github.springtestdbunit.DbUnitTestExecutionListener;
2import com.github.springtestdbunit.annotation.DatabaseSetup;
3import com.github.springtestdbunit.annotation.DbUnitConfiguration;
4import org.junit.experimental.categories.Category;
5import org.junit.runner.RunWith;
6import org.springframework.test.context.ContextConfiguration;
7import org.springframework.test.context.TestExecutionListeners;
8import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
9import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
10import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
11import org.springframework.test.context.web.WebAppConfiguration;
12
13@RunWith(SpringJUnit4ClassRunner.class)
14@ContextConfiguration(classes = {IntegrationTestContext.class})
15@WebAppConfiguration
16@TestExecutionListeners({
17 DependencyInjectionTestExecutionListener.class,
18 TransactionalTestExecutionListener.class,
19 DbUnitTestExecutionListener.class
20})
21@DatabaseSetup("messages.xml")
22@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
23@Category(IntegrationTest.class)
24public class GetMessageTest {
25
26}
Second, we have to register a new test execution listener called ServletTestExecutionListener. This test execution listener provides mock servlet API support for the WebApplicationContext objects which are loaded by the Spring Test framework.
After we have registered this test execution listener, the source code of our test class looks as follows:
1import com.github.springtestdbunit.DbUnitTestExecutionListener;
2import com.github.springtestdbunit.annotation.DatabaseSetup;
3import com.github.springtestdbunit.annotation.DbUnitConfiguration;
4import org.junit.experimental.categories.Category;
5import org.junit.runner.RunWith;
6import org.springframework.test.context.ContextConfiguration;
7import org.springframework.test.context.TestExecutionListeners;
8import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
9import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
10import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
11import org.springframework.test.context.web.ServletTestExecutionListener;
12import org.springframework.test.context.web.WebAppConfiguration;
13
14@RunWith(SpringJUnit4ClassRunner.class)
15@ContextConfiguration(classes = {IntegrationTestContext.class})
16@WebAppConfiguration
17@TestExecutionListeners({
18 DependencyInjectionTestExecutionListener.class,
19 TransactionalTestExecutionListener.class,
20 DbUnitTestExecutionListener.class,
21 ServletTestExecutionListener.class
22})
23@DatabaseSetup("messages.xml")
24@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
25@Category(IntegrationTest.class)
26public class GetMessageTest {
27
28}
Third, we have to add the following fields into our integration test class:
- The
webAppContextfield contains theWebApplicationContextobject that is loaded by the Spring Test framework. - The
mockMvcfield contains theMockMvcobject that we use when we write integration tests for our controllers.
After we have added these fields into our test class, its source code looks as follows:
1import com.github.springtestdbunit.DbUnitTestExecutionListener;
2import com.github.springtestdbunit.annotation.DatabaseSetup;
3import com.github.springtestdbunit.annotation.DbUnitConfiguration;
4import org.junit.experimental.categories.Category;
5import org.junit.runner.RunWith;
6import org.springframework.beans.factory.annotation.Autowired;
7import org.springframework.test.context.ContextConfiguration;
8import org.springframework.test.context.TestExecutionListeners;
9import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
11import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
12import org.springframework.test.context.web.ServletTestExecutionListener;
13import org.springframework.test.context.web.WebAppConfiguration;
14import org.springframework.test.web.servlet.MockMvc;
15import org.springframework.web.context.WebApplicationContext;
16
17@RunWith(SpringJUnit4ClassRunner.class)
18@ContextConfiguration(classes = {IntegrationTestContext.class})
19@WebAppConfiguration
20@TestExecutionListeners({
21 DependencyInjectionTestExecutionListener.class,
22 TransactionalTestExecutionListener.class,
23 DbUnitTestExecutionListener.class,
24 ServletTestExecutionListener.class
25})
26@DatabaseSetup("messages.xml")
27@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
28@Category(IntegrationTest.class)
29public class GetMessageTest {
30
31 @Autowired
32 private WebApplicationContext webAppContext;
33
34 private MockMvc mockMvc;
35}
Fourth, we have to create the MockMvc object that we use when we write integration tests for our controllers. We can create this object by following these steps:
- Add a setup method into our test class. We will create the required
MockMvcobject in this method. - Create a new
MockMvcobject by using the web application context based setup and set the created object to themockMvcfield.
After added a new setup method into our test class, its source code looks as follows:
1import com.github.springtestdbunit.DbUnitTestExecutionListener;
2import com.github.springtestdbunit.annotation.DatabaseSetup;
3import com.github.springtestdbunit.annotation.DbUnitConfiguration;
4import org.junit.Before;
5import org.junit.experimental.categories.Category;
6import org.junit.runner.RunWith;
7import org.springframework.beans.factory.annotation.Autowired;
8import org.springframework.test.context.ContextConfiguration;
9import org.springframework.test.context.TestExecutionListeners;
10import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
12import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
13import org.springframework.test.context.web.ServletTestExecutionListener;
14import org.springframework.test.context.web.WebAppConfiguration;
15import org.springframework.test.web.servlet.MockMvc;
16import org.springframework.test.web.servlet.setup.MockMvcBuilders;
17import org.springframework.web.context.WebApplicationContext;
18
19@RunWith(SpringJUnit4ClassRunner.class)
20@ContextConfiguration(classes = {IntegrationTestContext.class})
21@WebAppConfiguration
22@TestExecutionListeners({
23 DependencyInjectionTestExecutionListener.class,
24 TransactionalTestExecutionListener.class,
25 DbUnitTestExecutionListener.class,
26 ServletTestExecutionListener.class
27})
28@DatabaseSetup("messages.xml")
29@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
30@Category(IntegrationTest.class)
31public class GetMessageTest {
32
33 @Autowired
34 private WebApplicationContext webAppContext;
35
36 private MockMvc mockMvc;
37
38 @Before
39 public void configureSystemUnderTest() {
40 mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext)
41 .build();
42 }
43}
Additional Reading:
We have now configured the Spring MVC Test framework by using the web application context based configuration, and we can start writing integration tests for our controllers.
Let’s find out how we can configure the Spring MVC Test framework when we are using Spring Boot.
Writing Integration Tests for a Spring Boot Web Application
If we are writing integration tests for a web application that uses Spring Boot, we can configure the Spring MVC Test framework by following these steps:
First, we have to enable the auto-configuration of the Spring MVC Test framework. We can enable this Spring Boot feature by annotating our test class with the @AutoConfigureMockMvc annotation.
After we have annotated our test class with this annotation, the source code of our test class looks as follows:
1import com.github.springtestdbunit.DbUnitTestExecutionListener;
2import com.github.springtestdbunit.annotation.DatabaseSetup;
3import com.github.springtestdbunit.annotation.DbUnitConfiguration;
4import org.junit.experimental.categories.Category;
5import org.junit.runner.RunWith;
6import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
7import org.springframework.boot.test.context.SpringBootTest;
8import org.springframework.test.context.TestExecutionListeners;
9import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
11import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
12
13@RunWith(SpringJUnit4ClassRunner.class)
14@SpringBootTest(classes = {IntegrationTestContext.class})
15@AutoConfigureMockMvc
16@TestExecutionListeners({
17 DependencyInjectionTestExecutionListener.class,
18 TransactionalTestExecutionListener.class,
19 DbUnitTestExecutionListener.class
20})
21@DatabaseSetup("messages.xml")
22@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
23@Category(IntegrationTest.class)
24public class GetMessageTest {
25
26}
Second, we have to register a new test execution listener called ServletTestExecutionListener. This test execution listener provides mock servlet API support for the WebApplicationContext objects which are loaded by the Spring Test framework.
After we have registered this test execution listener, the source code of our test class looks as follows:
1import com.github.springtestdbunit.DbUnitTestExecutionListener;
2import com.github.springtestdbunit.annotation.DatabaseSetup;
3import com.github.springtestdbunit.annotation.DbUnitConfiguration;
4import org.junit.experimental.categories.Category;
5import org.junit.runner.RunWith;
6import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
7import org.springframework.boot.test.context.SpringBootTest;
8import org.springframework.test.context.TestExecutionListeners;
9import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
11import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
12import org.springframework.test.context.web.ServletTestExecutionListener;
13
14@RunWith(SpringJUnit4ClassRunner.class)
15@SpringBootTest(classes = {IntegrationTestContext.class})
16@AutoConfigureMockMvc
17@TestExecutionListeners({
18 DependencyInjectionTestExecutionListener.class,
19 TransactionalTestExecutionListener.class,
20 DbUnitTestExecutionListener.class,
21 ServletTestExecutionListener.class
22})
23@DatabaseSetup("messages.xml")
24@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
25@Category(IntegrationTest.class)
26public class GetMessageTest {
27
28}
Third, we have to add a new MockMvc field into our test class and ensure that the real MockMvc object is injected into this field by the Spring container.
After we have added this field into our test class, its source code looks as follows:
1import com.github.springtestdbunit.DbUnitTestExecutionListener;
2import com.github.springtestdbunit.annotation.DatabaseSetup;
3import com.github.springtestdbunit.annotation.DbUnitConfiguration;
4import org.junit.experimental.categories.Category;
5import org.junit.runner.RunWith;
6import org.springframework.beans.factory.annotation.Autowired;
7import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
8import org.springframework.boot.test.context.SpringBootTest;
9import org.springframework.test.context.TestExecutionListeners;
10import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
12import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
13import org.springframework.test.context.web.ServletTestExecutionListener;
14import org.springframework.test.web.servlet.MockMvc;
15
16@RunWith(SpringJUnit4ClassRunner.class)
17@SpringBootTest(classes = {IntegrationTestContext.class})
18@AutoConfigureMockMvc
19@TestExecutionListeners({
20 DependencyInjectionTestExecutionListener.class,
21 TransactionalTestExecutionListener.class,
22 DbUnitTestExecutionListener.class,
23 ServletTestExecutionListener.class
24})
25@DatabaseSetup("messages.xml")
26@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
27@Category(IntegrationTest.class)
28public class GetMessageTest {
29
30 @Autowired
31 private MockMvc mockMvc;
32}
Additional Reading:
We have now configured the Spring MVC Test framework by using the auto-configuration feature provided by Spring Boot, and we can start writing integration tests for our controllers.
Let’s summarize what we learned from this lesson.
Summary
This lesson has taught us two things:
- If we are writing integration tests for a Spring web application, we have to create the required
MockMvcobject by using the web application context based configuration. - If we are writing integration tests for a Spring Boot web application, we can create the required
MockMvcobject by using the auto-configuration feature of Spring Boot.