mockMVC单元测试(SpringBoot+Spring Security+Jwt)

狄峻熙
2023-12-01
import java.nio.charset.StandardCharsets;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
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.http.MediaType;
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 com.acoffee.pojo.LoginRequest;
import com.alibaba.fastjson.JSON;

@SpringBootTest
@AutoConfigureMockMvc//该注解将会自动配置mockMvc的单元测试
class DemoApplicationTests {

	@Autowired
	private MockMvc mockMvc;

传对象的情况

/**
	 * 1、mockMvc.perform执行一个请求。
	 * 2、MockMvcRequestBuilders.get("XXX")构造一个请求。
	 * 3、ResultActions.param添加请求传值
	 * 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型
	 * 5、ResultActions.andExpect添加执行完成后的断言。
	 * 6、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情
	 *   比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
	 * 7、ResultActions.andReturn表示执行完成后返回相应的结果。
*/
@Test
void login() throws Exception {
	LoginRequest loginRequest = new LoginRequest();
	loginRequest.setUsername("tom");
	loginRequest.setPassword("123456");

	MvcResult mvcResult = mockMvc
			.perform(MockMvcRequestBuilders.post("/api/auth/login")
					.accept(MediaType.parseMediaType("application/json;charset=UTF-8"))
					.contentType(MediaType.APPLICATION_JSON).content(JSON.toJSONString(loginRequest)))//import com.alibaba.fastjson.JSON;
			//断言:判断状态码  status().isBadRequest():400错误请求   status().isOk():正确   status().isNotFound():验证控制器不存在
			.andExpect(MockMvcResultMatchers.status().isOk())
			// 解析返回的json字段中的属性值是否与断言一样
			.andExpect(MockMvcResultMatchers.jsonPath("$.email").value("123456@qq.com"))
			.andDo(MockMvcResultHandlers.print()).andReturn();

	String content = mvcResult.getResponse().getContentAsString();//可以拿到返回的内容
	System.out.println(content);
}

执行结果:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/auth/login
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json;charset=UTF-8", Content-Length:"38"]
             Body = {"password":"123456","username":"tom"}
    Session Attrs = {}

Handler:
             Type = com.acoffee.controller.AuthController
           Method = com.acoffee.controller.AuthController#login(LoginRequest)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Content-Type:"application/json;charset=UTF-8", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = application/json;charset=UTF-8
             Body = {"token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0b20iLCJpYXQiOjE2NDg3ODIwMjYsImV4cCI6MTY0ODg2ODQyNn0.4gdn05fBVCM5OzJscCOFzimKeSnYJjedCO-uaSA7eAevAxS7SY1_gUt8E3n03RX72Isefok9OQuahZnswluNjA","type":"Bearer","id":1,"username":"tom","email":"123456@qq.com","roles":["ROLE_ADMIN"]}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
-------------------------------------------------
{"token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0b20iLCJpYXQiOjE2NDg3ODIwMjYsImV4cCI6MTY0ODg2ODQyNn0.4gdn05fBVCM5OzJscCOFzimKeSnYJjedCO-uaSA7eAevAxS7SY1_gUt8E3n03RX72Isefok9OQuahZnswluNjA","type":"Bearer","id":1,"username":"tom","email":"123456@qq.com","roles":["ROLE_ADMIN"]}

带 token 的情况

@Test
void testAdmin() throws Exception {
	MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/api/test/admin")
			//添加token由于我这里的token是Bearer类型的所以应该是"Bearer yourtoken"这种格式
			.header("Authorization","Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0b20iLCJpYXQiOjE2NDg3MTAzNzcsImV4cCI6MTY0ODc5Njc3N30.5jjk3gS_rsfPuMOjfNyLYDCq_yzjFxgzqaAgCVAWo79H1ZDd936hUx7YPvzEdRYLOygXXhf83FiCcS6Yn08oUg")
			.accept(new MediaType(MediaType.APPLICATION_JSON, StandardCharsets.UTF_8)))
			.andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print()).andReturn();
}

执行结果:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /api/test/admin
       Parameters = {}
          Headers = [Authorization:"Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0b20iLCJpYXQiOjE2NDg3MTAzNzcsImV4cCI6MTY0ODc5Njc3N30.5jjk3gS_rsfPuMOjfNyLYDCq_yzjFxgzqaAgCVAWo79H1ZDd936hUx7YPvzEdRYLOygXXhf83FiCcS6Yn08oUg", Accept:"application/json;charset=UTF-8"]
             Body = null
    Session Attrs = {}

Handler:
             Type = com.acoffee.controller.TestController
           Method = com.acoffee.controller.TestController#adminAccess()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Content-Type:"application/json;charset=UTF-8", Content-Length:"12", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = application/json;charset=UTF-8
     		 //模拟返回页面:不同权限看到的页面不一样
             Body = Admin Board.
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

断言的概念
所谓断言的概念指的是当程序执行到某些语句之后其数据的内容一定是约定的内容。

 类似资料: