axios-mock-adapter
axios-mock-adapter copied to clipboard
Wrong history of request when use an interceptor to re-send request with changed config
versions:
- node: 16.14.0
- adios-mock-adapter: 1.21.2
The history of request's config seems to be overwrite if it belongs to the same request.
Here is the demo code: I create a axios instance which will update the request's headers if server's response's data said statusCode is 401 (NOTE: not http status code), and re-send the request with the updated config.
The expectation is the first request header should not as same as the second. But the assertion always failed ( For reading convenience, I put the failed assertion at the end of the test case)
------------ netadapter.ts ----------------
import axios, {AxiosRequestHeaders} from "axios";
export class NetAdapter {
#accessToken: string | undefined = undefined
#instance = axios.create({
baseURL: 'http://192.168.1.1'
})
constructor() {
this.#instance.interceptors.response.use(async (res) => {
const originalConfig = res.config
if (res.status === 200 && res.data?.statusCode === 401) {
if (originalConfig.headers) {
originalConfig.headers = {
...originalConfig.headers,
accessToken: '123456',
}
} else {
originalConfig.headers = {
accessToken: '123456'
}
}
return await this.#instance.request(originalConfig)
}
return res
})
}
async call(api: string) {
const headers: AxiosRequestHeaders = this.#accessToken ? {accessToken: this.#accessToken} : {}
return await this.#instance.post(api, {}, {headers: headers})
}
setToken(token: string) {
this.#accessToken = token
}
}
-------------------- the test suits ---------------------
import {NetAdapter} from "../src/netadapter";
import MockAdapter from "axios-mock-adapter";
import axios from "axios";
import exp from "constants";
let adapter!: NetAdapter;
let mockAxios!: MockAdapter;
beforeAll(() => {
mockAxios = new MockAdapter(axios, {delayResponse: 200})
})
beforeEach(() => {
mockAxios.reset()
adapter = new NetAdapter()
})
describe('axios mock test', () => {
test('auto add token', async () => {
const expectUrl = '/abc'
mockAxios.onPost().replyOnce(200, {statusCode: 401}).onPost().replyOnce(200)
const res = await adapter.call(expectUrl)
expect(mockAxios.history.post.length).toBe(2)
expect(mockAxios.history.post[0].url).toContain(expectUrl)
expect(mockAxios.history.post[1].url).toContain(expectUrl)
expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual('123456')
expect(mockAxios.history.post[0]?.headers?.accessToken).toBeUndefined()
})
test('auto update token', async () => {
const expectUrl = '/abc'
mockAxios.onPost().replyOnce(200, {statusCode: 401}).onPost().replyOnce(200)
adapter.setToken('666')
const res = await adapter.call(expectUrl)
expect(mockAxios.history.post.length).toBe(2)
expect(mockAxios.history.post[0].url).toContain(expectUrl)
expect(mockAxios.history.post[1].url).toContain(expectUrl)
expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual('123456')
expect(mockAxios.history.post[0]?.headers?.accessToken).toEqual('666')
})
test('manual set token and send request instead of automation', async () => {
const expectUrl = '/abc'
const expectToken = 'fff'
mockAxios.onPost().reply(200)
await adapter.call(expectUrl)
adapter.setToken(expectToken)
const res = await adapter.call(expectUrl)
expect(mockAxios.history.post.length).toBe(2)
expect(mockAxios.history.post[0]?.headers?.accessToken).toBeUndefined()
expect(mockAxios.history.post[0].url).toContain(expectUrl)
expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual(expectToken)
expect(mockAxios.history.post[1].url).toContain(expectUrl)
})
})
-------------- the test results -------------------
FAIL test/NetAdapter.test.ts
axios mock test
✕ auto add token (423 ms)
✕ auto update token (414 ms)
✓ manual set token and send request instead of automation (417 ms)
● axios mock test › auto add token
expect(received).toBeUndefined()
Received: "123456"
26 | expect(mockAxios.history.post[1].url).toContain(expectUrl)
27 | expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual('123456')
> 28 | expect(mockAxios.history.post[0]?.headers?.accessToken).toBeUndefined()
| ^
29 | })
30 |
31 | test('auto update token', async () => {
at test/NetAdapter.test.ts:28:65
at fulfilled (test/NetAdapter.test.ts:5:58)
● axios mock test › auto update token
expect(received).toEqual(expected) // deep equality
Expected: "666"
Received: "123456"
39 | expect(mockAxios.history.post[1].url).toContain(expectUrl)
40 | expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual('123456')
> 41 | expect(mockAxios.history.post[0]?.headers?.accessToken).toEqual('666')
| ^
42 | })
43 |
44 | test('manual set token and send request instead of automation', async () => {
at test/NetAdapter.test.ts:41:65
at fulfilled (test/NetAdapter.test.ts:5:58)
Test Suites: 1 failed, 1 total
Tests: 2 failed, 1 passed, 3 total
Snapshots: 0 total
Time: 5.753 s
Ran all test suites.
error Command failed with exit code 1.