2017-06-07 61 views
4

我正在寫express.js路由的小型中間件,但是當我來單元測試時,我卡住了這段代碼,我不知道如何使用摩卡,sinon和chai正確地測試它。如何測試返回匿名函數的node.js模塊?

我中間件代碼有入口點是這樣的:

const searchByQuerystring = require('./search-by-querystring'); 
const searchByMarker = require('./search-by-marker'); 

module.exports = (req, res, next) => { 

    if (req.marker) { 
     searchByMarker(req, res, next); 
    } else if (req.query) { 
     searchByQuerystring(req, res, next); 
    } else { 
     next(); 
    } 
}; 

,並進行單元測試時,我想,以測試方法searchByMarkersearchByQuerystring被調用。

於是我開始寫這個測試,

it('Should call search by querystring if querystring is present',() => { 
    const req = httpMocks.createRequest({ 
      query: { 
       value: 1000 
      } 
     }), 
     res = httpMocks.createResponse(), 
     next = sandbox.spy(); 
    searchIndex(req, res, next); 

    sinon.assert.calledOnce(next); 
}); 

在我的中間件應該使用searchByQuerystring的處理請求,我想測試一下,如果searchByQuerystring方法被調用,但我真不」不知道該怎麼做,也許我應該以其他方式編寫這段代碼,我真的不想使用像proxyquire這樣的庫。

也許我的模塊做了太多的工作(根據單一責任原則) - 但整個中間件用於構建搜索對象,在開始時我只需要找出參數來自哪個地方,所以我認爲它是把這個邏輯放在中間件的啓動上 - 我應該只有兩個中間件?

請有任何幫助,對此的建議。

+0

除非您嘗試測試的函數可以以某種方式訪問​​,或者您可以驗證根據輸出調用了哪個函數,否則最好的辦法可能是依賴代碼覆蓋工具,如['istanbul'] (https://github.com/gotwarlost/istanbul)。 – mscdex

+0

謝謝@mscdex的建議! –

回答

0

好吧,

因此,把這篇文章幫助我找到解決方案。我重寫我的中間件切入點,來尋找這樣

const searchRequestParser = require('./search-request-parser'); 
const search = require('../../../lib/search'); 

module.exports = (req, res, next) => { 

    const searchRequest = searchRequestParser(req); 
    if (searchRequest) { 
    const searchCriteria = search(searchRequest.resourceToSearch); 
    req.searchQuery = 
    searchCriteria.buildQuery(searchRequest.queryParameters); 
    } 
    next(); 
}; 

和測試

it('Should call search by querystring if querystring is present',() => { 
    const req = httpMocks.createRequest({ 
      method: 'GET', 
      params: { 
       resourceToSearch: 'debts' 
      }, 
      query: { 
       value: 1000 
      } 
     }), 
     res = httpMocks.createResponse(), 
     next = sandbox.spy(); 
    searchIndex(req, res, next); 

    expect(req).to.have.a.property('searchQuery'); 
}); 

所以方法searchByMarkersearchByQuerystring都不見了和方法取代searchRequestParser與輸出,那麼我在代碼中處理該輸出,因爲它原來在方法中重複searchByMarkersear chByQuerystring

感謝我使用函數的返回輸出,我不必專注於模擬/存根這些函數。