Javascript 调用原始函数而不是存根

Javascript 调用原始函数而不是存根,javascript,express,mocha.js,stub,sinon,Javascript,Express,Mocha.js,Stub,Sinon,让Sinon的存根为我正确工作,我遇到了一个问题。当我在retro上存根list并运行测试时,app.get('/retro',retro.list)正在执行原始函数retro.list,而不是存根。由于发生这种情况,测试失败,因为存根的callCount为0 我对咖啡脚本比较熟悉,我也用同样的方式把事情弄糟了。关于Javascript的作用域,或者require('../routes/retro')是如何工作的,或者retro在app.js和test.js中是不是不一样 非常感谢下面的帮助和代

让Sinon的存根为我正确工作,我遇到了一个问题。当我在
retro
上存根
list
并运行测试时,
app.get('/retro',retro.list)
正在执行原始函数
retro.list
,而不是存根。由于发生这种情况,测试失败,因为存根的
callCount
为0

我对咖啡脚本比较熟悉,我也用同样的方式把事情弄糟了。关于Javascript的作用域,或者
require('../routes/retro')
是如何工作的,或者
retro
app.js
test.js
中是不是不一样

非常感谢下面的帮助和代码

test.js:

var request = require('supertest')
  , retro = require('../routes/retro')
  , app = require('../app')
  , sinon = require('sinon');
require('should'); 

describe('GET /retro', function() {
  // less involved, but maybe stupid to test
  it('should call retro.list', function(done) {
    var stub = sinon.stub(retro, 'list');

    request(app)
      .get('/retro')
      .end(function(err, res){
        stub.callCount.should.equal(1);

        if (err) return done(err);
        done();
      })
  })
})
app.js:

var express = require('express')
  , config = require('./config')
  , routes = require('./routes')
  , retro = require('./routes/retro');

var app = express();
config(app);

app.get('/', routes.index);
app.get('/retro', retro.list);

module.exports = app;
retro.js:

var retro = {
  list: function(req, res){
    console.log('actual called');
    res.send("respond with a resource");
  }
}

module.exports = retro;

在要求/创建
应用程序之前,您可能需要创建存根

var request = require('supertest')
  , sinon = require('sinon')
  , retro = require('../routes/retro');

var stubRetroList = sinon.stub(retro, 'list');

var app = require('../app');

// ...

    stubRetroList.callCount.should.equal(1);
这允许在将
追溯列表传递到路线之前对其进行更新:

app.get('/retro', retro.list);

问题可能是因为
retro.list
不是通过引用(指针)传递的,而是通过值(复制)传递的引用。因此,虽然
sinon.stub()
正在更改
retro.list
,但它不会影响
'/retro'
路由已经拥有的副本。

我面临同样的问题,而接受的答案(虽然是真的)没有帮助。结果表明,为了使
sinon
存根工作,存根方法不能在同一模块中使用。换句话说,存根模块端点只会存根模块端点,而不会存根
module.exports
引用的函数的内部用法

举例说明:

module.js

const express = require('express')
const router = express.Router()

router.get('/', function (req, res) {
  res.status(200).json(list())
})

function list() {
    return ['something']
}

module.exports = {
    router: router,
    list: list
}
module.spec.js

// This stub will not work
sinon.stub(module, 'list').callsFake(() => ['something else'])
要使其工作,您需要将要存根的内容分离到它自己的模块中,并以这种方式使用它:

sub_module.js

function list() {
    return ['something']
}

module.exports = {
    list: list
}
现在可以存根
子模块.list()


(OP定义了一个适当的方法,因此这对他来说不是问题)

什么是
retro
返回的?它是普通对象还是新创建的实例?试试这个
retro.list.callCount.should.equal(1)
@mor I包含了
retro.js
,因此您可以看到它返回的对象。这不是一个例子。我曾考虑导出一个实例并尝试存根原型,但效果也不太好。@Sushanth--我尝试了你的建议,但
sinon.stub(retro,'list')
retro.list
上返回存根,因此它们是相同的对象,运行该代码产生了相同的问题。谢谢你的建议谢谢乔纳森!这很有效。我不确定我是否喜欢在上面存根,但我很高兴我知道它是存根引用/副本,而不是同一个对象。这是一个更好的解决方案