【问题标题】:Mocking request object with Jasmine and Express使用 Jasmine 和 Express 模拟请求对象
【发布时间】:2017-05-25 10:14:03
【问题描述】:

我有一个很简单的方法:

module.exports = {
  login: function (username, password, req, res) {
    authModule.check_login({login: username, pass: password}).then(function (user) {
      req.session.regenerate(function () {
        req.session.user = username
        req.session.userID = user.id
        req.session.fullName = user.fullName
        req.session.email = user.email

        res.redirect('/user')
      })
    }).catch(function (err) {
      res.render('login', {
        unsuccessful: true
      })
    })
  }
}

在我的单元测试中,我试图验证此方法是否确实正确设置了会话变量。我一直在尝试使用jasmine.createSpy 模拟请求对象,但它似乎不起作用,例如:

describe('user_login.login', function () {
  it('sets the session vars', function (done) {
    let req = jasmine.createSpy('req')
    const res = {
      render: function (renderTemplate, renderValues) {
        let template = renderTemplate
        let values = renderValues
      }
    }
    const userLogin = require('../helpers/user_login')
    userLogin.login(process.env.USER, process.env.PASSWORD, req, res)
    expect(req.session.regenerate).toHaveBeenCalled()
    done()
  })
})

返回:

Failures:
1) user_login.login sets the session vars
  Message:
    TypeError: Cannot read property 'regenerate' of undefined

有什么方法可以让我在不向服务器发出请求的情况下访问会话变量?我正在尝试测试功能本身,而不是服务器。模拟请求对象的正确方法是什么?

感谢您的宝贵时间。

【问题讨论】:

    标签: node.js unit-testing express jasmine mocking


    【解决方案1】:

    hmm.. 您当前正在为请求对象创建一个间谍。但你实际上想监视 req.session.regenerate 函数。

    尝试用以下内容替换您的模拟请求:

    let req = {session: {regenerate: jasmine.createSpy('regenerate')}};
    

    【讨论】:

    • 感谢您的建议,但是,测试仍然失败(“Expected spy regenerate to have been called”)。
    • 我认为问题在于我真正想要监视的是regenerate 的回调,而不是regenerate 本身。但是我仍然在努力理解如何做到这一点......
    • 好的,但是现在测试失败了,至少出现了预期的错误消息:)
    • 好的,但是现在测试失败了,至少出现了预期的错误消息:) 还有一些其他问题: 1. 你的登录函数没有返回承诺。因此你不能在你的测试中使用它。所以将登录函数的开头更改为return authModule.check_login(.... 2. 然后在您的测试中,将实际测试和断言更改为:`userLogin.login(process.env.USER, process.env.PASSWORD, req, res).then (function() { expect(req.session.regenerate).toHaveBeenCalled(); done(); }) `
    • 问题是,你的登录功能是异步的。但是您的测试执行同步。因此,您在实际调用该函数之前测试该函数是否被调用。因此,您需要从您的登录方法返回承诺,以便在您的测试中等待(或等待登录完成的任何其他函数)
    【解决方案2】:

    好的,我想通了,感谢@ShabbY 的帮助:

    describe('user_login.login', function () {
      it('sets the session vars', function (done) {
        let req = {
          session: {
            regenerate: function (fn) {
              return fn()
            }
          }
        }
    
        const res = {
          render: function (renderTemplate, renderValues) {
            let template = renderTemplate
            let values = renderValues
          }
        }
        const userLogin = require('../helpers/user_login')
        spyOn(req.session, 'regenerate').and.callThrough()
        userLogin.login(process.env.USER, process.env.PASSWORD, req, res)
        .then(function () {
          expect(req.session.user).toBe('myUser')
          done()
        })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-18
      • 2021-07-15
      • 2020-01-17
      • 2015-04-15
      • 2018-03-01
      • 1970-01-01
      • 2017-02-26
      相关资源
      最近更新 更多