[英]How to mock interceptors when using jest.mock('axios')?
When running a test using jest I have the basic test suit syntax:使用 jest 运行测试时,我有基本的测试服语法:
jest.mock('axios');
describe('app', () => {
let render
beforeEach(() => {
axiosMock.get.mockResolvedValueOnce({
data: {greeting: 'hello there'},
}),
render= renderApp()
});
test('should render something', () => {
expect(something).toBeInTheDocument();
});
});
The problem is I have interceptors in my code which when running the test with jest command outputs:问题是我的代码中有拦截器,当使用 jest 命令输出运行测试时:
TypeError: Cannot read property 'interceptors' of undefined
类型错误:无法读取未定义的属性“拦截器”
and points to the interceptors object并指向拦截器对象
axiosInstance.interceptors.request.use(...
axiosInstance
is the a variable storing the return of axios.create
axiosInstance
是存储axios.create
返回值的axios.create
export const axiosInstance = axios.create({...
Refered to this axios thread on SO How do I test axios in jest but it doesn't involve any interceptors so didn't really help.在 SO How do I test axios in jest上参考了这个 axios 线程,但它不涉及任何拦截器,所以并没有真正的帮助。
This was enough in the end, plain and simple jest.fn()
这最终就足够了,简单明了
jest.fn()
jest.mock('axios', () => {
return {
interceptors: {
request: { use: jest.fn(), eject: jest.fn() },
response: { use: jest.fn(), eject: jest.fn() },
},
};
});
Make sure to mock out the interceptors and axios.create
if used:如果使用,请确保模拟拦截器和
axios.create
:
// Replace any instances with the mocked instance (a new mock could be used here instead):
axios.create.mockImplementation((config) => axios);
// Mock out the interceptor (assuming there is only one):
let requestCallback = () => {
console.log("There were no interceptors");
};
axios.interceptors.request.use.mockImplementation((callback) => {
requestCallback = callback;
});
// Mock out the get request so that it returns the mocked data but also calls the
// interceptor code:
axios.get.mockImplementation(() => {
requestCallback();
return {
data: "this is some data"
};
});
Note if this doesn't work:请注意,如果这不起作用:
This example assumes that the create and interceptor calls are in a place where Jest can mock them out.此示例假定创建和拦截器调用位于 Jest 可以模拟它们的位置。 Placing the
axios.create
or axiosInstance.interceptors.request.use
lines outside the scope of the function may cause the above mocking to fail.将
axios.create
或axiosInstance.interceptors.request.use
行放在函数范围之外可能会导致上述axiosInstance.interceptors.request.use
失败。 This is an example file where Jest can mock them out:这是一个示例文件,Jest 可以在其中模拟它们:
const axios = require('axios');
const DEBUG = true;
const customRequest = (url) => {
// Example of axios.create from https://www.npmjs.com/package/axios#axioscreateconfig
const axiosInstance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
// Example of interceptor taken from https://stackoverflow.com/a/52737325/7470360:
axiosInstance.interceptors.request.use((config) => {
if (DEBUG) { console.info("Request called", config); }
return config;
}, (error) => {
if (DEBUG) { console.error("Request error ", error); }
return Promise.reject(error);
});
return axiosInstance.get(url);
}
module.exports = customRequest;
The mocking code will mock out the axios.create
call and the axiosInstance
calls in customRequest
.模拟代码将模拟出
customRequest
的axios.create
调用和axiosInstance
调用。 Moving either the creation or interception outside the function will cause the mocks to fail.将创建或拦截移动到函数之外将导致模拟失败。
Here is how I mocked axios.create
and its interceptors
:这是我嘲笑
axios.create
及其interceptors
:
jest.mock('axios', () => {
return {
create: () => {
return {
interceptors: {
request: {eject: jest.fn(), use: jest.fn()},
response: {eject: jest.fn(), use: jest.fn()},
},
};
},
};
});
Afterwards I was able to call the following in my test code:之后,我能够在我的测试代码中调用以下内容:
const client = axios.create({
baseURL: 'http://some-url.com',
});
client.interceptors.request.use(config => {
// some other test code
return config;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.