簡體   English   中英

如何在nodejs上使用mocha對控制台輸出進行單元化?

[英]How to unit test console output with mocha on nodejs?

考慮以下示例Javascript代碼:

function privateFunction (time) {
  if (time < 12) { console.log('Good morning'); }
  if (time >= 12 && time <19) { console.log('Good afternoon'); }
  else { console.log('Good night!'); }
};

我應該如何使用mocha(也可能是sinonjs)對nodejs進行單元測試,注意到這是一個在模塊內部調用的私有函數? 我需要傳入參數並檢查函數是否正在將正確的東西記錄到控制台。

我可以用console.warnconsole.error做同樣的事情嗎?

我更喜歡mocha-sinon不是“普通”的sinon,因為它與Mocha完美融合。

例:

var expect = require('chai').expect;
require('mocha-sinon');

// Function to test, can also be in another file and as long as it's
// being called through some public interface it should be testable.
// If it's not in any way exposed/exported, testing will be problematic.
function privateFunction (time) {
  if (time < 12) { console.log('Good morning'); }
  if (time >= 12 && time <19) { console.log('Good afternoon'); }
  else { console.log('Good night!'); }
}

describe('privateFunction()', function() {

  beforeEach(function() {
    this.sinon.stub(console, 'log');
  });

  it('should log "Good morning" for hours < 12', function() {
    privateFunction(5);
    expect( console.log.calledOnce ).to.be.true;
    expect( console.log.calledWith('Good morning') ).to.be.true;
  });

  it('should log "Good afternoon" for hours >= 12 and < 19', function() {
    privateFunction(15);
    expect( console.log.calledOnce ).to.be.true;
    expect( console.log.calledWith('Good afternoon') ).to.be.true;
  });

  it('should log "Good night!" for hours >= 19', function() {
    privateFunction(20);
    expect( console.log.calledOnce ).to.be.true;
    expect( console.log.calledWith('Good night!') ).to.be.true;
  });

});

一個潛在的問題:一些Mocha記者也使用console.log ,因此存在它的測試可能不會產生任何輸出。

有一種解決方法,但它並不理想,因為它會將Mocha輸出與privateFunction()的輸出散布在一起。 如果這不是問題,請用以下內容替換beforeEach()

beforeEach(function() {
  var log = console.log;
  this.sinon.stub(console, 'log', function() {
    return log.apply(log, arguments);
  });
});

忽略這是一個私人功能的事實,我會采取幾個步驟; 重構我的代碼以更好地分離關注點,並將此分離與測試雙打一起使用。

  • 將所有副作用帶到自己的模塊中(此處的副作用是寫入控制台):

    out.js

     function log (message) { console.log(message); }; module.exports = {log}; 

    app.js

     const {log} = require('out'); function greeter (time) { if (time < 12) { log('Good morning'); } if (time >= 12 && time < 19) { log('Good afternoon'); } else { log('Good night!'); } }; module.exports = {greeter}; 
  • 使用一些模塊代理/間諜,比如proxyquire在測試時替換整個編寫器

    app.spec.js

     describe('output writers', function(){ const fakeOut = { log: sinon.spy(), }; const app = proxyquire('./app', { 'out': fakeOut }); it('should log to the fake out', function(){ app.greeter(15); assert(fakeOut.log.calledOnce); }); }); 

如果您的目的僅僅是測試控制台輸出,我會建議在方法調用上使用以下內容而不是存根/間諜等:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM