简体   繁体   English

调用原始函数而不是存根

[英]Original function is called instead of stub

I'm having an issue getting Sinon's stub to work correctly for me. 我有一个问题让Sinon的存根正常工作。 When I stub list on retro and the test runs, app.get('/retro', retro.list) is executing the original function retro.list instead of the stub. 当我在retro上存根list并且测试运行时, app.get('/retro', retro.list)正在执行原始函数retro.list而不是存根。 Since this happens, the test fails because the stub's callCount is 0. 由于发生这种情况,测试失败,因为存根的callCount为0。

I'm more familiar with coffeescript and I have stubbed things in the same way. 我对coffeescript更熟悉,而且我用同样的方式抄袭了东西。 Is there something I'm not understanding about Javascript's scoping, or how the require('../routes/retro') works, or is retro is not the same in app.js and test.js . 有没有我不了解Javascript的范围,或者require('../routes/retro')工作的,或者app.jstest.js retro是不一样的。

Much thanks for the help and code below. 非常感谢下面的帮助和代码。

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: 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: retro.js:

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

module.exports = retro;

You'll likely need to create your stubs before requiring/creating the app . 在需要/创建app之前,您可能需要创建存根。

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

This allows retro.list to be updated before it's passed to the route: 这允许retro.list在传递给路径之前更新:

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

The issue is probably because retro.list isn't being passed-by-reference (pointer), but is rather a reference that's passed-by-value (copied). 问题可能是因为retro.list不是通过引用传递(指针),而是一个传递值(复制)的引用。 So, though sinon.stub() is altering retro.list , it wouldn't affect the copy that the '/retro' route already had. 因此,虽然sinon.stub()正在改变retro.list ,但它不会影响'/retro'路径已经拥有的副本。

I faced the same issue and the accepted answer (while true) was of no help. 我遇到了同样的问题,接受的答案(虽然是真的)没有任何帮助。 Turns out in order for sinon stubbing to work the stubbed method cannot be used in the same module. 原来为了使sinon工作, sinon方法不能在同一个模块中使用。 In other words stubbing a module endpoint will only stub the module endpoint and not the internal usage of the function referenced by module.exports . 换句话说,对模块端点进行存根只会对模块端点进行存根,而不module.exports引用的函数进行内部使用。

Explained via an example: 通过一个例子解释:

module.js 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 module.spec.js

// This stub will not work
sinon.stub(module, 'list').callsFake(() => ['something else'])

To make it work you have separate what you want to stub into its own module and use it that way: 为了使它工作,你将你想要存根的东西分成它自己的模块并以这种方式使用它:

sub_module.js sub_module.js

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

module.exports = {
    list: list
}

Now sub_module.list() can be stubbed. 现在sub_module.list()可以被存根。

(OP defines a method in place so this is not an issue for him) (OP定义了一种方法,所以这对他来说不是问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM