Call a stub module function in the same module
P粉596161915
P粉596161915 2023-11-03 13:47:45
0
2
702

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

P粉596161915
P粉596161915

reply all(2)
P粉099000044

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:

export const fooWrapper = {
    foo() {...}
}

function bar () {
    return fooWrapper.foo()
}

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 to exports where the input is any).

P粉797855790

I just tested this. It works like a charm.

'use strict'

function foo () {
  return 'foo';
}

exports.foo = foo;

function bar () {
  return exports.foo(); // <--- notice
}

exports.bar = bar;

When you do sinon.stub(myModule, 'foo').returns('foo2'), sinon will stub the exported object's foo is not the actual foo function in myModule.js... As you must know, foo is available from outside the module access. So when you set exports.foo, the exported object exports.foo stores the ref of foo. When you call sinon.stub(myModule, 'foo').returns('foo2'), sinon will stub exports.foo which is not the actual foo

Hope this makes sense!

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template