2013-08-01 93 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定義的方法到位,因此這對他來說並不是一個問題)

相關問題