Reputation: 142
I am using an axios interceptor to add authorization token to its header. The interceptor works fine.
//api.js
import { getAccessToken } from "./utils";
const apiInstance = axios.create();
apiInstance.interceptors.request.use((configIns) => {
const token = getAccessToken();
configIns.headers.Authorization = token ? `Bearer ${token}` : "";
return configIns;
});
export { apiInstance };
Here is my test file to test the interceptor.
// api.test.js
import { apiInstance } from "./api"
import {getAccessToken} from "./utils";
describe("request interceptor", () => {
it("API request should add authorization token to header", () => {
const getAccessToken = jest.fn(getAccessToken);
getAccessTokenMock.mockReturnValue("token");
const result = apiInstance.interceptors.request.handlers[0].fulfilled({ headers: {} });
expect(getAccessTokenMock.mock.calls.length).toBe(1);
expect(result.headers).toHaveProperty("Authorization");
});
});
However the getAccessToken
function in not getting mocked for some reason inside the interceptor.
The test fails.
Upvotes: 3
Views: 11524
Reputation: 481
That's not how mocks in Jest work. By calling (I assume variable should be getAccessTokenMock
, not getAccessToken
):
const getAccessTokenMock = jest.fn(getAccessToken);
getAccessTokenMock.mockReturnValue("token");
What you do is: you create new local mock, that when called, would call your getAccessToken
function. Then you mock return value. However, your getAccessTokenMock
is never called, because it's not the same instance as in your implementation!
What you need to do is mock your actual function getAccessToken
from your ./utils
file. It can be done, for example, like this:
import { apiInstance } from "./api"
import {getAccessToken} from "./utils";
// Mock here:
jest.mock('./utils', () => ({
getAccessToken: jest.fn(() => 'token')
});
describe("request interceptor", () => {
it("API request should add authorization token to header", () => {
const result = apiInstance.interceptors.request.handlers[0].fulfilled({ headers: {} });
expect(getAccessToken.mock.calls.length).toBe(1);
expect(result.headers).toHaveProperty("Authorization");
});
});
What is happening here is that when file is loaded, jest.mock
would run first and would replace your implementation of getAccessToken
with the mock - it would be then accessible from both implementation and test (as the same instance), meaning that you can verify if it has been called.
Please find more about mocks here or here. Alternatively you can also use spyOn
to achieve similar result (then you don't need jest.mock
, but you have to import your getAccessToken
function without destructuring).
Upvotes: 4