正當我高高興興寫完後臺c層的測試代碼準備提交時,測試機器人報了不少401錯誤,把代碼拉下來一看,原來當我寫代碼時,個人夥伴已經寫好後臺的攔截器了,只有綁定了token的用戶才能訪問後臺,因此當我單元測試c層模擬請求時就會報錯,
json
由於個人模擬前臺請求就像是一個沒有登錄的用戶請求,通過攔截器必然是被攔截了下來。
dom
一開始有點不知所錯。咱們的模擬請求失敗是由於後臺在沒有綁定token的狀況下請求了其餘接口,而咱們的攔截器也沒有發token給模擬請求。咱們正常要使用系統的話要先登陸,第一次登陸的話後臺會發送一個token給前臺並與用戶綁定,之後就會帶着後臺發來的token去請求。
因此首先模擬一下正常的登陸流程。創造一個方法loginUser()
,在方法上添加註釋@Before
,用於在每一個測試方法前執行。在這個先新建一個用戶用來當咱們的模擬用戶,咱們用這個用戶的username和password來進行登陸,而後在進行請求。函數
@Test public void loginUser() throws Exception { String url = "/user/login"; String username = RandomString.make(6); String password = RandomString.make(6); JSONObject jsonObject = new JSONObject(); jsonObject.put("username", username); jsonObject.put("password", password); // 當以參數username, password調用userService.login方法時,返回true Mockito.when(this.userService.login(username, password)).thenReturn(true); // 觸發C層並斷言返回值 this.mockMvc.perform(MockMvcRequestBuilders.post(url) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(jsonObject.toJSONString())) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("true")); }
可是兩次模擬請求並非同一個用戶,咱們須要在第一次請求的時候獲取token並保存用戶,在後續請求攜帶token發出模擬請求。這就須要引入request類。
上述方法太麻煩了,在學長的建議下,研究攔截器原理,發現攔截器經過isLogin()函數裏判斷token來判斷這個用戶是否登錄過,若是把isLogin方法mock一下,讓他永遠返回true就不管傳什麼token就均可以不被攔截了。post
@Before public void loginUser() throws Exception { Mockito.when(this.userService.isLogin(Mockito.any(String.class))).thenReturn(true); }
可是隻是在mock方法裏規定傳入string類型是不行的,咱們模擬請求默認token是null,因此咱們應該在模擬請求時加入header的token信息,隨意一個字符串就好。單元測試
this.mockMvc.perform( MockMvcRequestBuilders.get(url) .header("auth-token", "key") .param("page", "1") .param("size", "2")) .andExpect(MockMvcResultMatchers.status().isOk());
咱們也能夠在mock方法裏設置傳入任一參數都返回true,這樣咱們就不用在後續模擬請求中發送token了。測試
@Before public void loginUser() throws Exception { Mockito.when(this.userService.isLogin(Mockito.any())).thenReturn(true); }
不斷改進本身的解決辦法,從中學到更多解決問題的方法,同時加深了對攔截器和token的瞭解。ui