Sinon.spy is not called in a method
The code I'm testing is pretty simple: it calls a method when a condition is checked. If not, it calls another method contained in 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 installed spy for each method, but spy for method fn
does not work while spy for contained method is running subFn
. 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
})
})
})
Having inflicted something wrong with the spy on the function fn
, I tried with two separate methods. Both spies do not work 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 on what I am doing wrong?
source to share
I haven't found the exact solution, but the workaround is pretty close to it. So the problem seems to be related to how the this.fn
using is handled sinon.spy
, instead of this:
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')
This is because of what I use this
to store fn
and subFn
.
source to share