【问题标题】:Stubbing express middleware functions with sinon is用 sinon 存根 express 中间件函数是
【发布时间】:2019-02-05 08:01:37
【问题描述】:

说明

我尝试为快速中间件功能设置存根假货,但它并没有被替换。

我正在尝试什么(如何重现)

我正在尝试通过 callsFake 函数使用 sinon 存根,正如他们最新文档中所建议的那样。

即使我需要模块并在导出时从属性中替换函数。我一直看到原来的函数行为在起作用。

我知道我应该在设置中间件函数之前尝试将函数存根,那是第一次导入 express app 的时候。

这是我要存根的函数,定义为函数并导出为对象。它是在一个脚本文件中定义的,其路径类似于api/middlewares/stripe/signature

const stripeHelper = require('../../../lib/stripe')
const logger = require('../../../lib/logger')
const verifySignature = (req, res, next) => {
  var event
  let eventName = req.url.replace('/', '')
  try {
      // Try adding the Event as `request.event`
    event = stripeHelper.signatureCheck(
        eventName,
        req.body,
        req.headers['stripe-signature']
      )
  } catch (e) {
      // If `constructEvent` throws an error, respond with the message and return.
    logger.error('Error while verifying webhook request signature', e.message, e)
    return res.status(400).send('Webhook Error:' + e.message)
  }
  req.event = event
  next()
}
module.exports.verifySignature = verifySignature

我已经尝试过的

  • 使用 decache 确保 express 应用实例是原始的,并且没有使用以前的原始中间件进行初始化
  • 设置多个 beforEach 挂钩以组织我的存根和前提条件或测试

不断发生的事情

  • 原来的中间件函数被执行
  • 我没有看到存根函数的任何日志(作为 sinon 存根不工作的第二个证据

这是我的存根和测试挂钩设置:

const chai = require('chai')
const chaiHttp = require('chai-http')
const dirtyChai = require('dirty-chai')
const sinon = require('sinon')
const decache = require('decache')
const signatureMiddleware = require('../../../api/middlewares/stripe/signature')
const bp = require('body-parser')
let verifySignatureStub, rawStub

chai.should()
chai.use(dirtyChai)
chai.use(chaiHttp)

const API_BASE = '/api/subscriptions'
const planId = 'NYA-RUST-MONTHLY'
const utils = require('../../utils')
const {
  hooks: {createSubscription, emitPaymentSucceeded},
  stripe: {generateEventFromMock}
} = utils

let testUser, testToken, testSubscription, server

describe.only('Subscriptions renewal (invoice.payment_succeeded)', function () {
  this.timeout(30000)

  beforeEach(function (done) {
    createSubscription(server, {planId}, function (err, resp) {
      if (err) return done(err)
      const {user, jwt, subscription} = resp
      console.log(user, jwt)
      testUser = user
      testToken = jwt
      testSubscription = subscription
      done()
    })
  })

  beforeEach(function (done) {
    verifySignatureStub = sinon.stub(signatureMiddleware, 'verifySignature')
    rawStub = sinon.stub(bp, 'raw')
    rawStub.callsFake(function (req, res, next) {
      console.log('bp raw')
      return next()
    })
    verifySignatureStub.callsFake(function (req, res, next) {
      const {customerId} = testUser.stripe
      const subscriptionId = testSubscription.id
      console.log('fake verify')
      req.event = generateEventFromMock('invoice.payment_failed', {subscriptionId, customerId, planId})
      return next()
    })
    done()
  })

  beforeEach(function (done) {
    decache('../../../index')
    server = require('../../../index')
    const {customerId} = testUser.stripe
    const {id: subscriptionId} = testSubscription
    console.log(`emitting payment succeeded with ${customerId}, ${subscriptionId} ${planId}`)
    emitPaymentSucceeded(server, testToken, function (err, response) {
      if (err) return done(err)
      done()
    })
  })

  afterEach(function (done) {
    verifySignatureStub.restore()
    done()
  })

  it('Date subscription will renew gets set to a valid number roughly one month', function () {
    // Not even getting here becasue calling the original function contains verifyMiddleware which should be replaced
  })

  it('Current period end is modified')

  it('An invoice for the new starting period is generated')

  it('Subscription status keeps active')
})

上下文(请填写以下信息):

所有都在节点 8 上运行,我正在使用 mocha 运行测试并使用脏 chai 进行设置。

这些是我的开发依赖项:

"devDependencies": { "base64url": "^2.0.0", "cross-env": "^5.0.5", "decache": "^4.4.0", "dirty-chai": "^2.0.1", "faker": "^4.1.0", "google-auth-library": "^0.12.0", "googleapis": "^23.0.0", "minimist": "^1.2.0", "mocha": "^5.2.0", "nodemon": "^1.12.0", "nyc": "^11.2.1", "sinon": "^6.1.5", "standard": "^10.0.3", "stripe-local": "^0.1.1" }

公开问题

https://github.com/sinonjs/sinon/issues/1889

【问题讨论】:

    标签: javascript node.js testing mocha.js sinon


    【解决方案1】:

    根据经验,应在每个测试中设置存根,即在beforeEachit 中,而不是在before 中。在这里,它们似乎不包含每个测试的逻辑,但它们可以,在这种情况下,它们不会像 before 那样按预期工作。 mocha-sinon 最好用于Mocha 与Sinon 沙箱的集成,所以恢复存根不需要afterEach,这是自动完成的。

    由于verifySignature 是导出属性而不是导出本身,signatureMiddleware 模块可以保持原样,但使用它的模块应该在预期使用@987654329 的测试中取消缓存并重新导入@。如果整个测试套件的行为应该相同,则也应该在 beforeEach 中执行。例如。如果这些中间件直接用在app模块中,就是:

    const decache = require('decache');
    
    ...
    
      describe(() => {
        let app;
    
        beforeEach(() => {
          verifySignatureStub = sinon.stub(signatureMiddleware, 'verifySignature');
          ...
        });
    
        beforeEach(() => {
          decache('./app');
          app = require('./app');
        });
    

    【讨论】:

    • 所以从你的角度来看,拥有多个 beforeEach 钩子可以吗?
    • 在 Mocha 或其他单元测试框架中拥有多个 beforeEach 肯定没问题,这允许组合块,也包括来自父 describe 的块。
    猜你喜欢
    • 2017-05-14
    • 2019-05-20
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多