【问题标题】:Writing jest test for chained functions in node.js在 node.js 中为链式函数编写笑话测试
【发布时间】:2019-02-12 18:53:17
【问题描述】:

我有一个想用 jest 测试的函数,该函数基本上会进行一些令牌验证并需要 3 个参数

这是我要测试的函数的解码代码:

const verifyToken = (req, res, next) => {
    // check header or url parameters or post parameters for token
    var token = req.headers['x-access-token']

    if (!token) return res.status(403).send({ auth: false, message: 'No token provided.' })

    // verifies secret and checks expire date
    jwt.verify(token, config.secret, (err, decoded) => {
        if (err) return res.status(500).send({ auth: false, message: 'Failed to authenticate token.' })

        //put user inside req.user to use the user in other routes
        User.findById(decoded.id, (err, user) => {
            if (err) {
                return res.status(500).json({
                    message: err
                })
            } else if (!user) {
                return res.status(404).json({
                    message: 'No user found'
                })
            } else {
                req.user = user
            }
            next()
        })
    })
}

所以我正在编写第一个测试,它测试是否在请求中没有给出令牌,它会发送带有消息的 403。以下是测试。

const verifyToken = require('../../config/token')

describe('veryfiy token tests', () => {
    it('Should give 403 status when no token is present', () => {
        let mockReq = {
            headers: {}
        }
        var mockRes = {
            status: code => code
            send: message => message
        }

        let nextCalled = false

        let next = () => {
            nextCalled = true
        }

        expect(verifyToken(mockReq, mockRes, next)).toBe(403)
    })
})

现在测试通过并出现错误: TypeError: res.status(...).send 不是函数

当我从代码中的 res.status 中删除 .send() 时,测试通过了。

我一直试图弄清楚如何在 res 对象上同时模拟 status() 和 send()。但还没有找到解决办法。

Tnx

【问题讨论】:

    标签: javascript node.js unit-testing express jestjs


    【解决方案1】:

    我认为问题在于res.status() 的结果没有一个名为send() 的函数。

    试试这个:

      var mockRes = {
        status: code => ({
          send: message => ({code, message})
        }),
      };
    

    你应该能够测试:

      var result = verifyToken(mockReq, mockRes, next);
      expect(result.code).toBeDefined();
      expect(result.code).toBe(403);
    

    PS:没有测试过代码:)

    【讨论】:

    • 这成功了!我不知道我必须嵌套函数。以 tnx 为例!
    【解决方案2】:

    你可以制作链式模拟类并测试,函数是否执行。

    这是一个例子。

      class MockResponse {
        constructor() {
        this.res = {};
         }
         status = jest
         .fn()
         .mockReturnThis()
         .mockImplementationOnce((code) => {
           this.res.code = code;
          return this;
         });
        send = jest
        .fn()
        .mockReturnThis()
        .mockImplementationOnce((message) => {
          this.res.message = message;
          return this;
        });
        }
    

    现在使用这个模拟类进行测试。并检查给定的函数是否以给定的结果执行。 比如

      it("should not call next function, and return 401, if token has not been found", async () => {
          let res = new MockResponse(); // here i initialised instance of class
          let  next = jest.fn();
          let req = {cookies:""} // header or cookies where you are receiving token here in my case empty.
           await authentication(req, res, next); // here i used my mock res class
          expect(next).not.toHaveBeenCalled(); // you must check that next will not be called. 
          expect(res.status).toHaveBeenCalledWith(401);//you can check result of status
          expect(res.send).toHaveBeenCalledWith("not authenticated");// send() message in your function
        });
    

    【讨论】:

      猜你喜欢
      • 2021-12-25
      • 2019-07-23
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 2021-06-12
      相关资源
      最近更新 更多