如何使用 Jest 测试 header、axios.defaults.headers?
How to test header, axios.defaults.headers, with Jest?
在我的应用程序中,我有一个中间件来检查 req
中的令牌以访问私有路由:
const config = require('../utils/config');
const jwt = require('jsonwebtoken');
module.exports = function (req, res, next) {
let token = req.header('x-auth-token');
if (!token) {
return res.status(401).json({ msg: 'No token. Authorization DENIED.' });
}
try {
let decoded = jwt.verify(token, config.JWTSECRET);
req.user = decoded.user;
next();
} catch (err) {
return res.status(401).json({ msg: 'Token is invalid.' });
}
};
为了在我的程序的 Redux 操作中发送带有正确令牌的 req
,我调用了以下函数 setAuthToken() 来设置身份验证令牌:
import axios from 'axios';
const setAuthToken = token => {
if (token) {
axios.defaults.headers.common['x-auth-token'] = token;
} else {
delete axios.defaults.headers.common['x-auth-token'];
}
};
export default setAuthToken;
我使用 axios 和 setAuthToken() 函数的 Redux 操作:
export const addPost = (formData) => async (dispatch) => {
try {
//set the token as the header to gain access to the protected route POST /api/posts
if (localStorage.token) {
setAuthToken(localStorage.token);
}
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const res = await axios.post('/api/posts', formData, config);
// ...
} catch (err) {
// ...
}
};
如何编写测试 setAuthToken() 的测试?以下是我的尝试:
import axios from 'axios';
import setAuthToken from '../../src/utils/setAuthToken';
describe('setAuthToken utility function.', () => {
test('Sets the axios header, x-auth-token, with a token.', () => {
let token = 'test token';
setAuthToken(token);
expect(axios.defaults.headers.common['x-auth-token']).toBe('test token');
});
});
以下是我得到的错误:
TypeError: Cannot read property 'headers' of undefined
查了一下这个错误,好像是因为我的测试里面没有req
。如果是这样的话,我怎样才能re-write我的测试发送一个req
?如果不是,我做错了什么?
这是我的案例,我的项目中有一个__mocks__
目录。有一个被嘲笑的axios
。有关 __mocks__
目录的更多信息,请参阅 Manual mock
__mocks__/axios.ts
:
const axiosMocked = {
get: jest.fn()
};
export default axiosMocked;
当我运行你提供的测试时,得到了和你一样的错误。因为模拟的 axios
对象没有 defaults
属性。这就是您收到错误的原因。
import axios from 'axios';
import setAuthToken from './setAuthToken';
jest.unmock('axios');
describe('setAuthToken utility function.', () => {
test('Sets the axios header, x-auth-token, with a token.', () => {
let token = 'test token';
setAuthToken(token);
expect(axios.defaults.headers.common['x-auth-token']).toBe('test token');
});
});
所以我使用 jest.unmock(moduleName) 来使用真正的 axios
模块而不是模拟模块。
之后,一切正常。单元测试结果:
PASS src/Whosebug/64564148/setAuthToken.test.ts (10.913s)
setAuthToken utility function.
✓ Sets the axios header, x-auth-token, with a token. (5ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 13.828s
另一个可能的原因是您启用了 automock。检查命令和 jest.config.js
文件。
在我的应用程序中,我有一个中间件来检查 req
中的令牌以访问私有路由:
const config = require('../utils/config');
const jwt = require('jsonwebtoken');
module.exports = function (req, res, next) {
let token = req.header('x-auth-token');
if (!token) {
return res.status(401).json({ msg: 'No token. Authorization DENIED.' });
}
try {
let decoded = jwt.verify(token, config.JWTSECRET);
req.user = decoded.user;
next();
} catch (err) {
return res.status(401).json({ msg: 'Token is invalid.' });
}
};
为了在我的程序的 Redux 操作中发送带有正确令牌的 req
,我调用了以下函数 setAuthToken() 来设置身份验证令牌:
import axios from 'axios';
const setAuthToken = token => {
if (token) {
axios.defaults.headers.common['x-auth-token'] = token;
} else {
delete axios.defaults.headers.common['x-auth-token'];
}
};
export default setAuthToken;
我使用 axios 和 setAuthToken() 函数的 Redux 操作:
export const addPost = (formData) => async (dispatch) => {
try {
//set the token as the header to gain access to the protected route POST /api/posts
if (localStorage.token) {
setAuthToken(localStorage.token);
}
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const res = await axios.post('/api/posts', formData, config);
// ...
} catch (err) {
// ...
}
};
如何编写测试 setAuthToken() 的测试?以下是我的尝试:
import axios from 'axios';
import setAuthToken from '../../src/utils/setAuthToken';
describe('setAuthToken utility function.', () => {
test('Sets the axios header, x-auth-token, with a token.', () => {
let token = 'test token';
setAuthToken(token);
expect(axios.defaults.headers.common['x-auth-token']).toBe('test token');
});
});
以下是我得到的错误:
TypeError: Cannot read property 'headers' of undefined
查了一下这个错误,好像是因为我的测试里面没有req
。如果是这样的话,我怎样才能re-write我的测试发送一个req
?如果不是,我做错了什么?
这是我的案例,我的项目中有一个__mocks__
目录。有一个被嘲笑的axios
。有关 __mocks__
目录的更多信息,请参阅 Manual mock
__mocks__/axios.ts
:
const axiosMocked = {
get: jest.fn()
};
export default axiosMocked;
当我运行你提供的测试时,得到了和你一样的错误。因为模拟的 axios
对象没有 defaults
属性。这就是您收到错误的原因。
import axios from 'axios';
import setAuthToken from './setAuthToken';
jest.unmock('axios');
describe('setAuthToken utility function.', () => {
test('Sets the axios header, x-auth-token, with a token.', () => {
let token = 'test token';
setAuthToken(token);
expect(axios.defaults.headers.common['x-auth-token']).toBe('test token');
});
});
所以我使用 jest.unmock(moduleName) 来使用真正的 axios
模块而不是模拟模块。
之后,一切正常。单元测试结果:
PASS src/Whosebug/64564148/setAuthToken.test.ts (10.913s)
setAuthToken utility function.
✓ Sets the axios header, x-auth-token, with a token. (5ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 13.828s
另一个可能的原因是您启用了 automock。检查命令和 jest.config.js
文件。