MockMVC的使用

简介

MockMvc是一种基于Java和JUnit的测试框架,旨在测试Spring MVC应用程序的控制器层。它可以帮助我们模拟HTTP请求,检查响应值,以及发送表单数据和文件等。 MockMvc可以与其他测试组件(如JUnit和Hamcrest)结合使用,以模拟REST API端点或用户界面的操作。

Get请求

简单示例

创建一个简单的Controller:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/mockMcv")
public class MockMvcController {

    @GetMapping("/first/connect")
    public String testConnect() {
        String result = "Hello MockMVC";
        return result;
    }

}

创建测试类,使用MockMVC

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
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.MockMvcResultMatchers;
​
​
// webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT:
// 指示Spring Boot在随机且可用的端口上启动Web服务器,避免端口冲突
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// 自动配置MockMvc和Spring IOC容器
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
public class MockMvcControllerTest {
​
    @Autowired
    private MockMvc mockMvc;
​
    @Test
    public void testConnect() throws Exception {
        MvcResult mvcResult = mockMvc.perform(
                // Get请求,url为:/mockMcv/first/connect
                MockMvcRequestBuilders.get("/mockMcv/first/connect"))
                // 检查响应状态码是否为200
                .andExpect(MockMvcResultMatchers.status().isOk())
                // 返回一个MvcResult回调对象
                .andReturn();
        // 获取响应文本
        String content = mvcResult.getResponse().getContentAsString();
        // 通过断言来验证返回是否正确
        Assert.assertTrue(content.equals("Hello MockMVC"));
    }
​
}

直接启动Debug启动,请求成功:

注意点

上述示例中需要注意,@SpringBootTest注解需要括号中的内容

去掉@SpringBootTest括号中的内容,运行结果:

 

原因:@SpringBootTest注释用于在测试与Spring Boot应用程序的集成中启用Spring上下文,如果使用默认配置,那就是Mock模式,即加载一个伪造的Web环境,其中一些内容(例如HTTP会话和重定向)不实际触发,而只是返回一个默认值。

所以在测试期间尝试模拟HTTP请求并使用不实际存在的Session时,可能会从该会话对象中出现NullPointerException。

Get带参数

controller中新加一个带参数的Get请求:

@GetMapping("/connect/withParam")
public String testConnectWithParam(@RequestParam("id") Long id, @RequestParam("name") String name) {
    String result = "id:" + id + ",name:" + name;
    return result;
}

测试类新增对应的测试方法:

@Test
public void testConnectWithParam() throws Exception {
    MvcResult mvcResult = mockMvc.perform(
                MockMvcRequestBuilders.get("/mockMcv/connect/withParam")
                        // 通过param()存放各个请求参数
                        .param("id", "1")
                        .param("name", "MockMVC"))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andReturn();
    String content = mvcResult.getResponse().getContentAsString();
    Assert.assertTrue(content.contains("MockMVC"));
}

Debug启动,请求成功:

Post请求

示例

controller中新加一个带Body的Post请求:

@PostMapping("/connect/withBody")
public String testConnectWithBody(@RequestBody Map<String,String> requestBody) {
    String result = JSONArray.toJSONString(requestBody);
    return result;
}

新增一个Java对象存放值:

import lombok.Data;
import java.io.Serializable;
​
@Data
public class MockMVCInfo implements Serializable {
    private static final Long serializableID = -1L;
    private Long id;
    private String name;
}

测试类新增对应的测试方法:

@Test
public void testConnectWithBody() throws Exception {
    MockMVCInfo mockMVCInfo = new MockMVCInfo();
    mockMVCInfo.setId(3L);
    mockMVCInfo.setName("MockMVC");
    MvcResult mvcResult = mockMvc.perform(
            MockMvcRequestBuilders.post("/mockMcv/connect/withBody")
                    // 指定 header中的 Content-Type为 application/json
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                    // 通过content()存放Body的Json
                    .content(JSON.toJSONString(mockMVCInfo)))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andReturn();
    String content = mvcResult.getResponse().getContentAsString();
    Assert.assertTrue(content.contains("MockMVC"));
}

Debug启动,请求成功:

注意点

1.通过RequestBody传递值,就得使用.content()方法存放Json

2.Body中使用Json,需要在header中指定Content-Type为application/json,参考Postman:

 

posted @ 2023-05-08 20:01  LonZyuan  阅读(784)  评论(0编辑  收藏  举报