MockMvc和Mockito之酷炫使用

2022-10-29,

由于项目中需要添加单元测试,所以查询之后发现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")); // 2. demo service stub test
String stub = "except result";
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")); // 2. demo service stub test
String stub = "except result";
Mockito.when(demoService.demoShow()).thenReturn(stub);
Assert.assertEquals(stub, demoService.demoShow());
Mockito.verify(demoService).demoShow();
}
}

MockMvc和Mockito之酷炫使用的相关教程结束。

《MockMvc和Mockito之酷炫使用.doc》

下载本文的Word格式文档,以方便收藏与打印。