如何对调用 res.cookie 的 express 中间件函数进行单元测试

How to unit test express middleware function that calls res.cookie

我正在尝试使用 mocha、chai 和 sinon 对我自己的 express 中间件功能进行单元测试。

基本上这个函数会检查 req.query 上的 token 参数,如果存在,则添加值为 token 的 cookie。

function tokenRedirect(req, res, next) {
    const qs = require('querystring');

    if (req.query && req.query.token) {
        res.cookie('token', req.query.token);
    } else {
        next();
        return;
    }

    res.redirect('/');
}

我知道我可以做类似的事情:

res = { cookie: sinon.spy() };

然后

assert(res.cookie.calledWith('token', expectedToken));

但我想做的是检查 req.cookies 是否真的有我期望的 cookie,如下所示:

assert.equal(req.cookies.token, expectedToken);

问题在于 resreq 以及它们的所有属性只是我为测试创建的模拟,因此 res.cookie 并不是真正添加的实际 express 函数req 对象的 cookie。

如何将真正的 express res 对象传递给我的函数?有可能吗?

我希望我说得足够清楚,单元测试对我来说是一个新概念。

使用来自 Express 的实际 reqres 对象会在集成测试中失败更多(如果我错了请纠正我)。单元测试只关注您的代码,所有其他外部依赖项都应该被模拟,如果我在评论中错了,请再次纠正我。

不是用 sion 模拟 res,而是需要部分 mock/implement Express 使用 here 的逻辑。所以像(使用 Jest):

const tokenRedirect = require('../location/to/middleware/tokenRedirect')

describe('tokenRedirect', () => {
  /**
   * Mocked Express Request object.
   */
  let req

  /**
   * Mocked Express Response object.
   */
  let res

  /**
   * Mocked Express Next function.
   */
  let next = jest.fn()

  beforeEach(() => {
    req = {
      body: {}
    }

    res = {
      query: {},
      headers: {},
      data: null,
      json(payload) {
        this.data = JSON.stringify(payload)
      },
      cookie(name, value, options) {
          this.headers[name] = value
      }
    }

    next.mockReset()
  })

  test('should correctly set cookie', async () => {
    const expectedToken = 'expected'
    res.query.token = ''

    tokenRedirect(req, res, next)

    expect(res.headers.token).toBeDefined()
    expect(res.headers.token).toEqual(expectedToken)
  })
})