[英]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.js
和test.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.