單元測試如何模擬用戶請求

錯誤

正當我高高興興寫完後臺c層的測試代碼準備提交時,測試機器人報了不少401錯誤,把代碼拉下來一看,原來當我寫代碼時,個人夥伴已經寫好後臺的攔截器了,只有綁定了token的用戶才能訪問後臺,因此當我單元測試c層模擬請求時就會報錯,
image.pngjson

由於個人模擬前臺請求就像是一個沒有登錄的用戶請求,通過攔截器必然是被攔截了下來。
image.pngdom

解決通過

一開始有點不知所錯。咱們的模擬請求失敗是由於後臺在沒有綁定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"));

    }

image.png
可是兩次模擬請求並非同一個用戶,咱們須要在第一次請求的時候獲取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());

image.png
咱們也能夠在mock方法裏設置傳入任一參數都返回true,這樣咱們就不用在後續模擬請求中發送token了。測試

@Before
    public void loginUser() throws Exception {

      Mockito.when(this.userService.isLogin(Mockito.any())).thenReturn(true);
    }

總結

不斷改進本身的解決辦法,從中學到更多解決問題的方法,同時加深了對攔截器和token的瞭解。ui

相關文章
相關標籤/搜索