Stub模块函数从同一个模块调用

时间:2016-03-02 17:10:30

标签: node.js

我无法找到一种方法来存储从同一模块中调用的函数这个函数的定义(存根似乎不起作用)。这是一个例子:

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

这让我想起了Java静态函数,这些函数不是一成不变的(几乎)。

知道如何实现我想要做的事情吗?我知道在不同的模块中提取foo会起作用,但这不是我在这里要做的。我也知道在foo方法中使用关键字bar调用this也会有效,我对在这种情况下使用this感到困惑(因为我没有使用OOP。)

2 个答案:

答案 0 :(得分:9)

我刚试过这个。它就像魅力一样。

'use strict'

function foo () {
  return 'foo';
}

exports.foo = foo;

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

exports.bar = bar;
  

解释

当您执行sinon.stub(myModule, 'foo').returns('foo2')时,sinonexported对象的foo与您foo内的实际myModule.js函数存根...您必须知道,foo可以从模块外部访问。因此,当您设置exports.foo时,导出的对象exports.foo会存储foo的ref。当您致电sinon.stub(myModule, 'foo').returns('foo2')时,sinon会存根exports.foo而非实际foo

希望这是有道理的!

答案 1 :(得分:0)

我对使用exports有点警惕,因为它有点神奇(例如,当您使用Typescript进行编码时,您永远不会直接使用它),所以我想提出一个替代解决方案,不幸的是,仍然需要修改源代码,这仅仅是将要存根的函数包装到对象中

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

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

还有sinon.stub(fooWrapper, 'foo')。只为进行测试而不得不像这样包装起来有点可惜,但至少它是显式的,并且在Typescript中是安全的(与exports(键入any相反)。