单元测试 auth.middleware.js 文件时出现 Jest 错误 Expect(jest.fn()).toHaveBeenCalledWith(...expected)

问题描述 投票:0回答:2

我试图找出为什么 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没有通过。 如果传递了格式错误的令牌。 如果传递了正确格式的令牌。

node.js unit-testing jestjs
2个回答
0
投票

您尝试像这样直接在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 属性,确保它具有用于测试的正确标记集。


0
投票

最后,我能够通过修改代码并相应地更改测试用例来解决我的问题。以下是这两个文件的更新代码。

[文件: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% 的代码。

© www.soinside.com 2019 - 2024. All rights reserved.