【发布时间】: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