SpringBoot+MockMvc测试Controller笔记整理

基础框架:Springboot(版本信息:1.5.6.RELEASE)

环境信息:JDK1.8

测试jar包:spring-boot-starter-test

之前在其它项目见过使用Mock进行单元测试,SpringMvc环境下可以直接模拟请求进来Controller的测试,相比常用的Sping Junit和Spring TestNG等也有一定的可借鉴之处,

本篇结合相关资料进行Mock测试,对基本步骤和注意点以及一些不明白的地方做个笔记,后续项目中如果遇到可以加深理解。

一、基本的SpringBoot环境搭建好之后基本上会包含所需要的jar包,测试类可以直接在生成的src/main/test目录下新建

二、测试示例:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class TestUserContorller {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void testGetUser() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/test/getUser.json").param("realName", "zhangsan")
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andDo(MockMvcResultHandlers.print())
            .andReturn();
    }
}
说明1:Spring4.2版本之后,已经用@SpringBootTest注解替换原先的注解,SpringMvc中会配置xml扫描来构建bean,SpringBoot中配置启动类即可以构建所有的bean,当然这个地方也可以只配置用到的bean

说明2:上述方式,适用于测试所有的Controller,一般测试单个Controller时都会推荐使用@SpringBootTest(classes = {MockServletContext.class}),然后构建MockMvc时使用mockMvc = MockMvcBuilders.standaloneSetup(new UserController()).build(); 其余的不变,对于请求测试的方法中不引用service bean的情况这种是可以的,但是若方法中涉及到service方法调用会抛出NullPonitException异常(@AutoWired注入的bean未初始化),目前还没找到解决办法,不过相信也是有解决方案的

附1:单个Controller测试完整示例

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {MockServletContext.class})
public class TestSimpleController {

    private MockMvc mockMvc;

    @Before
    public void init() {
        mockMvc = MockMvcBuilders.standaloneSetup(new UserController()).build();
    }

    @Test
    public void testGetUser() throws Exception {
        MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/test/kidding.json")
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andDo(MockMvcResultHandlers.print())
            .andReturn();
        System.out.println(result.getResponse().toString());
    }
}

附2:Mock测试单个Controller

public class TestSimpleController {

    /**
     * 用于注解Mock对象具体要注入到的那个对象
     * Controller类
     */
    @InjectMocks
    private UserController userController;

    /**
     * 用于注解在需要被Mock的对象上
     * Controller类所需要引用的bean
     */
    @Mock
    private UserService userService;

    private MockMvc mockMvc;

    /**
     * 初始化,模拟加载mvc的web测试环境
     */
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
    }

    @Test
    public void testGetUser() throws Exception {
        User user = new User();
        Mockito.when(userService.getUserByRealName("zhangsan")).thenReturn(user);
        Assert.assertNotNull(user);

        this.mockMvc.perform(MockMvcRequestBuilders.get("/test/getUser.json").param("realName", "zhangsan")
            .accept(MediaType.APPLICATION_JSON))
            .andDo(MockMvcResultHandlers.print())
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andReturn();
    }

说明:测试过程中发现模拟请求以及传参都是正确的,不过如果service层里dao层的引用调用则不会执行到但是不会报错。


你可能感兴趣的:(SpringBoot+MockMvc测试Controller笔记整理)