單元測試之Mock模擬對Controller進行測試

一、Mock測試介紹

  • 定義
    在單元測試過程中,對於某些不容易構造或者不容易獲取的對象,用一個虛擬對象來創建以便測試的方法。

  • 爲什麼使用mock測試

    ​ 對模塊進行集成測試時,希望能夠通過輸入URL對Controller進行測試,如果通過啓動服務器,建立http client進行測試(或者是通過Postman等工具),這樣會使得測試變得很麻煩,比如,啓動速度慢,測試驗證不方便,依賴網絡環境等,所以爲了可以對Controller進行測試,我們引入了MockMVC。
    ​ MockMvc實現了對Http請求的模擬,能夠直接使用網絡的形式,轉換到Controller的調用,這樣可以使得測試速度快、不依賴網絡環境,而且提供了一套驗證的工具,這樣可以使得請求的驗證統一而且很方便。

二、使用方式

使用起來很簡單,直接上代碼

1.controller控制器:

import com.example.demo.web.contract.BaseResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/main")
public class MainController {

    @GetMapping("/get")
    public BaseResponse getReq(@RequestParam Map<String, Object> map) {
        System.err.println(map);
        return new BaseResponse();
    }

    @PostMapping("/post")
    public BaseResponse postReq(@RequestBody Map<String, Object> map) {
        System.err.println(map);
        return new BaseResponse();
    }
    
    //put與delete方法與post同理,這裏就不寫了
    //…………

    @PostMapping(value = "/file")
    public BaseResponse file(@RequestPart("file") MultipartFile file) {
        System.err.println(file.getOriginalFilename());
        return new BaseResponse();
    }
}

2.測試代碼:

import com.alibaba.fastjson.JSON;
import com.example.demo.web.MainController;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
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.MockHttpServletRequestBuilder;
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;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class MvcTest {

    MockMvc mockMvc;

    @Autowired
    private WebApplicationContext applicationContext;

    @Autowired
    private MainController mainController;

    @Before
    public void before() {
        mockMvc = MockMvcBuilders.webAppContextSetup(applicationContext).build();

        //通過參數指定一組控制器,這樣就不需要從上下文獲取了
        //mockMvc = MockMvcBuilders.standaloneSetup(mainController).build();
    }

    /** get **/
    @Test
    public void getTest() throws Exception {

        MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders
                .get("/main/get")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .param("pageNum", "1");

        MvcResult mvcResult = mockMvc.perform(requestBuilder)
                .andDo(MockMvcResultHandlers.print()) //打印輸出發出請求的詳細信息
                .andExpect(MockMvcResultMatchers.status().isOk()) //對返回值進行斷言
                .andReturn();

        System.err.println(mvcResult.getResponse().getContentAsString());
    }

    /** post **/
    @Test
    public void postTest() throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("pageNum", 1);

        MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders
                .post("/main/post")
                //.put("/main/put")
                //.delete("/main/delete")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(JSON.toJSONString(map));

        MvcResult mvcResult = mockMvc.perform(requestBuilder)
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        System.err.println(mvcResult.getResponse().getContentAsString());
    }

    @Test
    public void fileTest() throws Exception {
        MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders
                .multipart("/main/file")
                .file(new MockMultipartFile("file", "test.txt",
                        "multipart/form-data",
                        "hello upload".getBytes("UTF-8")))
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON_UTF8);


        MvcResult mvcResult = mockMvc.perform(requestBuilder)
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        System.err.println(mvcResult.getResponse().getContentAsString());
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章