I can't find a way to stub a function called from the same module where the function is defined (stubbing doesn't seem to work). Here is an example:
myModule.js:
'use strict' function foo () { return 'foo' } exports.foo = foo function bar () { return foo() } exports.bar = bar
myModule.test.js:
'use strict' const chai = require('chai') const sinon = require('sinon') chai.should() const myModule = require('./myModule') describe('myModule', () => { describe('bar', () => { it('should return foo', () => { myModule.bar().should.equal('foo') // succeeds }) describe('when stubbed', () => { before(() => { sinon.stub(myModule, 'foo').returns('foo2') // this stub seems ignored }) it('should return foo2', () => { myModule.bar().should.equal('foo2') // fails }) }) }) })
This reminds me of Java static functions which are (almost) not stubable.
Any idea how to achieve what I'm trying to do? I know that extracting foo
in a different module will work, but that's not what I'm trying to do here. I also know that calling foo
using the keyword this
in the bar
method will also work, I'm not sure about using ̀this in this case
Confused (because I'm not using OOP).
I'm a bit wary of using
exports
since it's a bit magical (e.g. you never use it directly when coding in Typescript), so I wanted to propose an alternative solution, unfortunately The thing is that you still need to modify the source code, just wrap the function you want to stub into an object:and
sinon.stub(fooWrapper, 'foo')
. It's a bit of a shame that you have to wrap it like this just for testing, but at least it's explicit and type-safe in Typescript (as opposed toexports
where the input isany
).I just tested this. It works like a charm.
When you do
sinon.stub(myModule, 'foo').returns('foo2')
,sinon
will stubthe exported
object'sfoo
is not the actualfoo
function inmyModule.js
... As you must know,foo
is available from outside the module access. So when you setexports.foo
, the exported objectexports.foo
stores the ref offoo
. When you callsinon.stub(myModule, 'foo').returns('foo2')
,sinon
will stubexports.foo
which is not the actualfoo
Hope this makes sense!