我试图找出为什么 auth.middleware.js 文件测试失败。但是,找不到原因。
[文件:auth.middleware.js]
const { verifyJwtToken } = require('../helpers/jwt.helper');
const isAuthenticatedUser = function (req, res, next) {
const token = req?.headers?.authorization?.startsWith('Bearer').split(' ')[1];
if (!token) {
return res.status(401).json({
error: 'Authentication Failed',
});
}
try {
const jwtTokenPattern = /^Token\s[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/;
const tokenFormatMatched = jwtTokenPattern.test(token);
let rawToken = '';
if (tokenFormatMatched) {
rawToken = token.substr(token.indexOf(' ') + 1);
const decodedData = verifyJwtToken(rawToken);
req.user = decodedData;
next();
} else {
return res.status(401).json({
error: 'Authentication Failed',
});
}
} catch (err) {
res.status(401).json({
error: 'Authentication Failed',
});
}
};
module.exports = { isAuthenticatedUser };
[文件:auth.middleware.test.js]
const { verifyJwtToken } = require("../../../helpers/jwt.helper");
const { isAuthenticatedUser } = require("../../../middlewares/auth.middleware");
const jwtHelper = require("../../../helpers/jwt.helper");
const mockRequest = () => {
return {
headers: {
Authorization: "Bearer"
}
}
};
const mockResponse = () => {
return {
status: jest.fn().mockReturnThis(),
json: jest.fn().mockReturnThis()
}
};
const mockNext = jest.fn();
describe("Unit tests for auth.middleware.js file", () => {
it("Should check for missing authentication token error", () => {
//Arrange
const mockReq = mockRequest();
const mockRes = mockResponse();
//Act
isAuthenticatedUser(mockReq, mockRes, mockNext);
//Assert
expect(mockRes.status).toHaveBeenCalledWith(401);
expect(mockRes.json).toHaveBeenCalledWith({
error: "Authentication Failed"
});
expect(mockNext).not.toHaveBeenCalled();
});
it('should return a 401 error response when an error occurs when token is not valid', () => {
const mockReq = mockRequest().headers = { Authorization: 'Bearer validtoken' };
const mockRes = mockResponse();
isAuthenticatedUser(mockReq, mockRes, mockNext);
const verifyJwtTokenSpy = jest.spyOn(jwtHelper, "verifyJwtToken");
expect(verifyJwtTokenSpy).toHaveBeenCalledWith('validToken');
expect(mockRes.status).toHaveBeenCalledWith(401);
expect(mockRes.json).toHaveBeenCalledWith({
error: 'Authentication Failed'
});
expect(mockNext).not.toHaveBeenCalled();
});
});
[输出] 期望(jest.fn()).toHaveBeenCalledWith(...期望)
Expected: "validToken"
Number of calls: 0
42 | const verifyJwtTokenSpy = jest.spyOn(jwtHelper, "verifyJwtToken");
43 |
> 44 | expect(verifyJwtTokenSpy).toHaveBeenCalledWith('validToken');
| ^
45 | expect(mockRes.status).toHaveBeenCalledWith(401);
46 | expect(mockRes.json).toHaveBeenCalledWith({
47 | error: 'Authentication Failed'
at Object.<anonymous> (__tests__/unit/middlewares/auth.middleware.test.js:44:31)
我想为 isAuthenticatedUser 函数编写单元测试。我想测试 3 个场景。
如果token没有通过。 如果传递了格式错误的令牌。 如果传递了正确格式的令牌。
您尝试像这样直接在mockRequest函数中修改mockReq对象的 headers 属性,
const mockRequest = () => {
return {
headers: {
Authorization: "Bearer"
}
}
}
但是,当您调用mockRequest()时,它每次都会返回一个新对象,并且您并没有修改这个返回的对象,而是将其传递给isAuthenticatedUser。因此,在您的测试用例中,mockReq 仍然将 Authorization 标头设置为“Bearer”,并且您没有使用有效令牌更新它。
创建 mockReq 对象后,您需要在该对象上设置 Authorization 标头。您可以在测试用例中调用 isAuthenticatedUser 之前执行此操作。
const mockReq = mockRequest()
mockReq.headers.Authorization = 'Bearer validToken' // ...set the Authorization header with a valid token
通过这种方式,您可以修改将在测试用例中使用的mockReq对象的 headers 属性,确保它具有用于测试的正确标记集。
最后,我能够通过修改代码并相应地更改测试用例来解决我的问题。以下是这两个文件的更新代码。
[文件:auth.middleware.js]
const { verifyJwtToken } = require('../helpers/jwt.helper');
const isAuthenticatedUser = function (req, res, next) {
try {
if (!req?.headers?.authorization?.startsWith('Bearer')) {
return res.status(401).json({
error: 'Authentication Failed',
});
}
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({
error: 'Authentication Failed',
});
}
const decodedData = verifyJwtToken(token);
req.user = decodedData;
next();
} catch (err) {
res.status(401).json({
error: 'Authentication Failed',
});
}
};
module.exports = { isAuthenticatedUser };
[文件:auth.middleware.test.js]
const { isAuthenticatedUser } = require("../../../middlewares/auth.middleware");
const mockRequest = () => {
return {
headers: {
authorization: "Bearer"
}
}
};
const mockResponse = () => {
return {
status: jest.fn().mockReturnThis(),
json: jest.fn().mockReturnThis()
}
};
const mockNext = jest.fn();
describe("Unit tests for auth.middleware.js file", () => {
it("Should check for missing authentication token error", () => {
//Arrange
const mockReq = mockRequest().headers = { headers: {} };
const mockRes = mockResponse();
//Act
isAuthenticatedUser(mockReq, mockRes, mockNext);
//Assert
expect(mockRes.status).toHaveBeenCalledWith(401);
expect(mockRes.json).toHaveBeenCalledWith({
error: "Authentication Failed"
});
expect(mockNext).not.toHaveBeenCalled();
});
it("Should return a 401 error response when an error occurs when token is not valid", () => {
//Arrange
const mockReq = mockRequest().headers = { headers: { authorization: "Bearer validtoken" } };
const mockRes = mockResponse();
//Act
isAuthenticatedUser(mockReq, mockRes, mockNext);
//Assert
expect(mockRes.status).toHaveBeenCalledWith(401);
expect(mockRes.json).toHaveBeenCalledWith({
error: 'Authentication Failed'
});
expect(mockNext).not.toHaveBeenCalled();
});
it("Should return a 401 error when no authentication token is passed", async () => {
//Arrange
const mockReq = mockRequest();
const mockRes = mockResponse();
//Act
isAuthenticatedUser(mockReq, mockRes, mockNext);
//Assert
expect(mockRes.status).toHaveBeenCalledWith(401);
expect(mockRes.json).toHaveBeenCalledWith({
error: "Authentication Failed"
});
expect(mockNext).not.toHaveBeenCalled();
});
});
现在,我的所有测试都通过了。而且,它覆盖了我 100% 的代码。