javascript - 使用 sinon 进行快速中间件函数的 stub 是

标签 javascript node.js testing mocha.js sinon

描述

我尝试为快速中间件功能设置 stub 假冒,但它没有替换。

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

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

即使我需要该模块并替换导出时属性中的函数。我不断看到原始函数行为起作用。

我知道我应该尝试在中间件函数设置之前对函数进行 stub 处理,而这正是首次导入express app 的时候。

这是我试图 stub 的函数,定义为函数并导出为对象。它在脚本文件中定义,路径类似于 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 Hook 以组织我的 stub 和前提条件或测试

不断发生的事情

  • 执行原始中间件函数
  • 我没有看到 stub 函数的任何日志(作为 sinon stub 函数不起作用的第二个证据

这是我的 stub 和测试 Hook 设置:

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')
})

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

所有内容都在 Node 8 上运行,我正在使用 mocha 运行测试,并使用 dirty chai 进行设置。

这些是我的开发依赖项:

“开发依赖项”:{ "base64url": "^2.0.0", "跨环境": "^5.0.5", "decache": "^4.4.0", "脏柴": "^2.0.1", "faker": "^4.1.0", "google-auth-library": "^0.12.0", "googleapis": "^23.0.0", "极简主义": "^1.2.0", "Mocha ": "^5.2.0", “nodemon”:“^1.12.0”, "纽约": "^11.2.1", "sinon": "^6.1.5", “标准”:“^10.0.3”, “条纹本地”:“^0.1.1” }

未决问题

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

最佳答案

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

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

const decache = require('decache');

...

  describe(() => {
    let app;

    beforeEach(() => {
      verifySignatureStub = sinon.stub(signatureMiddleware, 'verifySignature');
      ...
    });

    beforeEach(() => {
      decache('./app');
      app = require('./app');
    });

关于javascript - 使用 sinon 进行快速中间件函数的 stub 是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52095939/

相关文章:

javascript - 如何应对 async/await hell ?

javascript - Electron 和 Node : How to read an SQL file?

reactjs - Jest 意外标识符 : React

通过分布式 jmeter 实例和 bamboo 进行性能测试

javascript - 启用和禁用 onkeydown 事件?

javascript - IE8/9 AJAX/CORS (XDomainRequest) 发送referer头

node.js - 在Mongoosejs中,如何检测和设置数据库连接超时?

javascript - 动态语言文档

java - 在 Java 中测试并发性

javascript - HighChart 系列中的自定义符号