2013-08-01 69 views
4

我有一个问题让Sinon的存根工作正常工作。当我存根listretro并且测试运行时,app.get('/retro', retro.list)正在执行原始功能retro.list而不是存根。由于出现这种情况,因为测试存根的callCount为0原函数被调用而不是stub

我更熟悉的CoffeeScript,我还以同样的方式存根事情失败。有没有什么我不了解Javascript的范围,或者require('../routes/retro')的工作原理,或者retroapp.jstest.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; 
+0

是什么'retro'返回?它是一个普通对象还是一个新创建的实例? – mor

+1

尝试这个'retro.list.callCount.should.equal(1);' –

+0

@mor我包括'复古。js'所以你可以看到它返回的对象。这不是一个实例。我正在考虑导出一个实例并试图对原型进行存根,但是这种方法的效果并不好。 – kmanzana

回答

7

你可能需要之前需要创建您的存根/创建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); 

这使得之前它传递到路线retro.list被更新:因为retro.list没有被通过,通过引用(指针),相反却是一个

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

的问题可能通过值传递的参考(复制)。所以,虽然sinon.stub()正在改变retro.list,但它不会影响'/retro'路线已有的副本。

+0

谢谢乔纳森!这工作完美。我不知道我喜欢在那里扼杀某些东西,但是我很高兴我明白它是一个参考文献/副本,而不是同一个客体。 – kmanzana

+0

[proxyquire](https://github.com/thlorenz/proxyquire)是一个更好的解决方案 – kmanzana

0

我面临同样的问题,接受的答案(虽然是真的)没有帮助。结果为了使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 
} 

现在sub_module.list()可以被桩住。

(OP定义的方法到位,因此这对他来说并不是一个问题)

相关问题