如何单元测试表示调用res.cookie的中间件函数

时间:2018-02-20 15:15:08

标签: unit-testing express mocha sinon chai

我正在尝试使用mocha,chai和sinon对我自己的快速中间件函数进行单元测试。

此功能基本上检查token上的req.query参数,如果存在,则添加值为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不是真正添加cookie的实际快速函数req对象。

如何将真正的快速res对象传递给我的函数?它甚至可能吗?

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

1 个答案:

答案 0 :(得分:1)

使用来自Express的实际reqres对象会更多地受到集成测试的影响(如果我错了,请纠正我)。单元测试只关注你的代码和所有其他外部依赖项应该被嘲笑,如果我在评论中错了,请再次纠正我。

您需要部分模拟/实现Express使用here的逻辑,而不是使用res模拟sion。所以像(使用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)
  })
})
相关问题