sinon:如何模拟从另一个函数返回的函数

我正在尝试使用simple-git 。 我需要编写一些unit testing,为此我需要使用sinon来模拟一些函数。 我遇到的问题是,我的嘲笑不传播到我的testing文件。

例如,在testing的文件中,我有这样的:

const git = require('simple-git/promise') function func () { var promise if (repo_exists()) { promise = git().silent(true).clone('http://github.com/me/my-repo.git') } else { promise = git('my-repo').silent(true).pull('origin','master') } promise.then(() => { // do more stuff }) } 

在我的testing文件中,我试过这个:

 const git = require('simple-git/promise')() sinon.stub(git, 'silent').callsFake(() => { return { clone: () => { console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~') console.log('calling clone') console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~') return new Promise((resolve, reject) => { console.log('clone') resolve() }) }, pull: () => { console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~') console.log('calling pull') console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~') return new Promise((resolve, reject) => { console.log('pull') resolve() }) } } }) 

但是嘲弄的function不会被调用。 我假设原因是require('simple-git/promise')返回一个函数,它本身返回包含我想模拟的函数的对象,但我不知道如何处理这个。

你是对的,当git()被调用时,它每次都会返回一个新的对象。 这个对象的方法最终被代理到一个Git的实例( https://github.com/steveukx/git-js/blob/master/src/git.js

作为选项,您可以_run内部_run方法(负责调度要执行的命令的方法):

 const Git = require('simple-git/src/git'); sinon.stub(Git.prototype, '_run').callsFake(function (command, cb) { console.log('called command', command) // to indicate success (will resolve eventual promise) cb.call(this, null, 'any message'); // OR to indicate failure (will reject eventual promise) Git.fail(this, 'error message', cb); return this; }); 

注意,在callsFake下的非箭头函数对于保存this是非常重要的,并且return this是为了遵守原始的行为( https://github.com/steveukx/git-js/blob/master/src/git.js#L1271 ) 。