Sinon.spy on a method is not invoked

試著忘記壹切 提交于 2019-12-24 00:33:15

问题


The code I'm testing is fairly simple: it invokes a method in case a condition is verified. If not, it invokes another method contained within the first one as an attribute.

app.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

I've set a spy on each method but the spy on the fn method does not seem to work while the spy on the contained method subFn works. See below:

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

Smelling something wrong with the spy on the fn function, I've tried with two separate methods. Both spies fail in this case:

app.js:

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

  return subFn('bar')
}

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

Any suggestion of what I'm doing wrong?


回答1:


I did not find the exact solution but a workaround quite close from one. So the problem seems to lie with the way this.fn is handled withtin sinon.spy, thus instead of doing:

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

We do the following:

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

The is easd by the fact that I use this to store fn and subFn.



来源:https://stackoverflow.com/questions/34795934/sinon-spy-on-a-method-is-not-invoked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!