【问题标题】:Check if dispatch action is called in axios interceptor using Jest检查是否使用 Jest 在 axios 拦截器中调用调度操作
【发布时间】:2019-10-22 01:09:36
【问题描述】:

我想测试每次出现未经授权的请求或响应状态码 401 时是否调用 loginReset() 函数。

我的代码如下:

使用-request.js

import axios from "axios"
import { axiosDefaultOptions } from "../config"
import { useSelector, useDispatch } from "react-redux"
import { loginReset } from "../store/reducers/login-slice"

const useRequest = (auth=false) => {
  const request = axios.create(axiosDefaultOptions)
  const dispatch = useDispatch()

  if(auth){
    const token = useSelector( state => state.login.data ? state.login.data.accessToken : null )
    request.interceptors.request.use(config => {
      config.headers.Authorization =  token ? `Bearer ${token}` : ''
      return config
    })  

    request.interceptors.response.use(response => {
      return response
    }, error => {
      if(error.response.status === 401) {
        dispatch(loginReset())
      }
      return Promise.reject(error)
    })
  }

  return request
}

export default useRequest

使用-request.test.js

import { testHookwithStore } from "../utils"
import faker from "faker"
import { useRequest } from "../../components/hooks"
import configureStore from "redux-mock-store"
import MockAdapter from "axios-mock-adapter"
import { axiosDefaultOptions } from "../../components/config"
import thunk from "redux-thunk"


describe("useRequest", () => {

  faker.seed(123);
  let request = null
  let authRequest = null
  let token = faker.random.uuid()
  const mockStore = configureStore([thunk])
  let authRequestAdapter = null
  const fakeDomainWord = faker.internet.domainWord()
  const fakeUrl = `${axiosDefaultOptions.baseURL}/${fakeDomainWord}`

  beforeEach(() => {
    let store = mockStore({
      login: { data: { accessToken: token } }
    })
    testHookwithStore(store, () => {
      request = useRequest()
      authRequest = useRequest(true)

      authRequestAdapter = new MockAdapter(authRequest)
      authRequestAdapter.onPost(fakeDomainWord, {}).reply(401, { code: 401, message: "Bad credentials" })
    })
  })

  test("Request should have no headers", () => {
    request.interceptors.request.use( config => {
      expect(config.headers.Authorization).toBeNull()
    })
  })

  test("Auth request should have Authentication Headers", () => {
    authRequest.interceptors.request.use( config => {
      expect(config.headers.Authorization).toBe(`Bearer ${token}`)
    })
  })

  test("Auth request resets login when 401", async () => {
    const loginReset = jest.fn()
    try{
      await authRequest.post(fakeUrl, {})
    }
    catch(error){
      expect(loginReset).toHaveBeenCalledTimes(1)
    }
  })
})

testHookwithStore 基本上只是创建一个包装在提供者周围的组件。最后一个测试失败了,我不确定如何验证调度是否真的有效。这里有什么线索吗?

【问题讨论】:

  • 你确定拦截器的测试工作正常吗?因为我做的测试和你的完全一样,所以我可以放任何东西而且我的测试是绿色的(而标题不是)。

标签: reactjs redux react-redux jestjs axios


【解决方案1】:

显然,模拟商店中有一个getActions() 函数。

test("Auth request resets login when 401", async () => {
    try{
      await authRequest.post(fakeUrl, {})
    }
    catch(error){
      expect(store.getActions()[0].type).toBe("loginReset")
    }
})

【讨论】:

    猜你喜欢
    • 2019-03-27
    • 2020-06-23
    • 1970-01-01
    • 2020-05-13
    • 2020-09-20
    • 2021-01-18
    • 2019-04-28
    • 1970-01-01
    • 2021-05-04
    相关资源
    最近更新 更多