不调用方法上的 Sinon.spy

Sinon.spy on a method is not invoked

本文关键字:Sinon spy 调用 方法      更新时间:2023-09-26

我正在测试的代码相当简单:它在验证条件时调用一个方法。如果不是,它将调用第一个方法中包含的另一个方法作为属性。

应用.js:

function test (fn, isActivated) {
  if (isActivated) {
    return fn('foo')
  }
  return fn.subFn('bar')
}
var fn = function (p) { return p }
fn.subFn = function (p) { return 'sub-' + p }
var resFn = test(fn, true)
var resSubFn = test(fn, false)
document.write(resFn) // shows 'foo' as expected
document.write(resSubFn) // shows 'bar' as expected

我已经在每种方法上设置了一个间谍,但是fn方法上的间谍似乎不起作用,而对所包含方法的间谍subFn工作。见下文:

app.test.js:

'use strict'
const chai = require('chai')
const sinon = require('sinon')
const trigger = require('../app').trigger
chai.should()
describe('test app', function () {
    before(function () {
      this.fn = function () {}
      this.fn.subFn = function () {}
      this.subFnSpy = sinon.spy(this.fn, 'subFn')
      this.fnSpy = sinon.spy(this.fn)
    })
    describe('isActivated is true', function () {
      before(function () {
        trigger(this.fn, true)
      })
      it('should invoke fn', function () {
        this.fnSpy.callCount.should.equal(1) // return false because callCount = 0
      })
    })
    describe('isActivated is false', function () {
      before(function () {
        trigger(this.fn, false)
      })
      it('should invoke subFn', function () {
        this.subFnSpy.callCount.should.equal(1) // return false because callCount = 0
      })
    })
  })

嗅到间谍对fn功能有问题,我尝试了两种不同的方法。在这种情况下,两个间谍都失败了:

应用.js:

exports.trigger = function (fn, subFn, isActivated) {
  if (isActivated) {
    return fn('fn')
  }
  return subFn('bar')
}

应用测试.js

'use strict'
const chai = require('chai')
const sinon = require('sinon')
const trigger = require('../app').trigger
chai.should()
describe('test app', function () {
    before(function () {
      this.fn = function () {}
      this.subFn = function () {}
      this.fnSpy = sinon.spy(this.fn)
      this.subFnSpy = sinon.spy(this.subFn)
    })
    beforeEach(function () {
      this.fnSpy.reset()
      this.subFnSpy.reset()
    })
    describe('isActivated is true', function () {
      before(function () {
        trigger(this.fn, this.subFn, true)
      })
      it('should invoke fn if isActivated is true', function () {
        this.fnSpy.callCount.should.equal(1) // return false
      })
    })
    describe('isActivated is false', function () {
      before(function () {
        trigger(this.fn, this.subFn, false)
      })
      it('should invoke subFn if isActivated is true', function () {
        this.subFnSpy.callCount.should.equal(1) // return false
      })
    })
  })

对我做错了什么有什么建议吗?

我没有

找到确切的解决方案,但有一个非常接近的解决方法。所以问题似乎在于this.fnsinon.spy的情况下处理的方式,因此而不是这样做:

this.fnSpy = sinon.spy(this.fn)
this.subFnSpy = sinon.spy(this.subFn)

我们做到以下几点:

this.fnSpy = sinon.spy(this, 'fn')
this.subFnSpy = sinon.spy(this.fn, 'subFn')

我使用this来存储fnsubFn这一事实很容易。