由於項目中需要添加單元測試,所以查詢之后發現Mockito非常適合現在的web項目。
首先需要添加pom依賴:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.5</version> </dependency>
在ControllerTest類上需要添加如下配置:
//XML風格 @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration(value = "src/main/webapp") @ContextHierarchy({ @ContextConfiguration(name = "parent", locations = "classpath:spring-config.xml"), @ContextConfiguration(name = "child", locations = "classpath:spring-others.xml") })OR
//注解風格
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration(value = "src/main/webapp")
@ContextHierarchy({
@ContextConfiguration(name = "parent", classes = AppConfig.class),
@ContextConfiguration(name = "child", classes = MvcConfig.class)
})
MockMvc為spring測試下的一個非常好用的類,配合Mockito使用能達到非常好的效果,他們的初始化需要在setUp中進行,具體代碼如下:
@Autowired private WebApplicationContext wac; private MockMvc mockMvc;@Mock
private DemoService demoService;@Before
public void setUp() throws Exception {
// 構造appcontext
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
// 初始化Mock
MockitoAnnotations.initMocks(this);
}
這樣mockMvc和Mockito的方法就可以在下面順利使用了,例如:
@Test public void testHelloWorld() throws Exception { // 1. controller mvc test MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/demo/hello"))
.andExpect(MockMvcResultMatchers.handler().handlerType(DemoController.class))
.andExpect(MockMvcResultMatchers.handler().methodName("helloWorld"))
.andExpect(MockMvcResultMatchers.view().name("demo/hello"))
.andExpect(MockMvcResultMatchers.model().attributeExists("msg"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn(); Assert.assertNotNull(result.getModelAndView().getModel().get("msg"));</span><span style="color: #008000;">//</span><span style="color: #008000;"> 2. demo service stub test</span> String stub = "except result"<span style="color: #000000;">; Mockito.when(demoService.demoShow()).thenReturn(stub); Assert.assertEquals(stub, demoService.demoShow()); Mockito.verify(demoService).demoShow();
}
MockMvc可以對controller中的一次調用進行模擬,perform就是一次請求,MockMvcRequestBuilders進行url的請求,andExcept方法為對Controller類、調用方法、視圖和model的預期設置,andDo進行這次請求的執行,最后andReturn返回。
Mockito通過方法when()、thenReturn()等方法可以對方法進行打樁,讓后續方法按照自己的數據樁來返回,達到了隔離依賴的效果。
整體的測試代碼如下:
import com.demo.service.DemoService; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextHierarchy; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext;/**
DemoControllerTest.
*/
//注解風格
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration(value = "src/main/webapp")
@ContextHierarchy({
@ContextConfiguration(name = "parent", locations = "classpath:spring-config.xml")
})
public class DemoControllerTest {@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;@Mock
private DemoService demoService;@Before
public void setUp() throws Exception {
// 構造appcontext
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
// 初始化Mock
MockitoAnnotations.initMocks(this);
}@Test
public void testIndex() throws Exception {
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/demo/"))
.andExpect(MockMvcResultMatchers.handler().handlerType(DemoController.class))
.andExpect(MockMvcResultMatchers.handler().methodName("index"))
.andExpect(MockMvcResultMatchers.view().name("demo/index"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();Assert.assertNotNull(result.getModelAndView().getViewName());
}
@Test
public void testHelloWorld() throws Exception {
// 1. controller mvc test
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/demo/hello"))
.andExpect(MockMvcResultMatchers.handler().handlerType(DemoController.class))
.andExpect(MockMvcResultMatchers.handler().methodName("helloWorld"))
.andExpect(MockMvcResultMatchers.view().name("demo/hello"))
.andExpect(MockMvcResultMatchers.model().attributeExists("msg"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
Assert.assertNotNull(result.getModelAndView().getModel().get("msg"));</span><span style="color: #008000;">//</span><span style="color: #008000;"> 2. demo service stub test</span> String stub = "except result"<span style="color: #000000;">; Mockito.when(demoService.demoShow()).thenReturn(stub); Assert.assertEquals(stub, demoService.demoShow()); Mockito.verify(demoService).demoShow();
}
}