2015-06-03 14 views
19

tener conto della seguente esempio di codice javascript di seguito:come unità di uscita della console di test con la moka sul nodejs

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

Come devo unit test che in nodejs utilizzando moka (e possibilmente sinonjs), notando che questo è una funzione privata chiamata all'interno di un modulo? Devo passare l'argomento e controllare se la funzione sta registrando la cosa giusta sulla console.

Posso fare lo stesso con console.warn e console.error?

risposta

26

Preferisco mocha-sinon sul sinon "semplice" perché si integra perfettamente con Mocha.

Esempio:

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; 
    }); 

}); 

Un potenziale problema: alcuni reporter moka usano console.log e, in modo che le prove stub potrebbe non produrre alcun output.

C'è una soluzione alternativa, ma non è l'ideale neanche perché intersputerà l'output Mocha con l'output da privateFunction(). Se questo non è un problema, sostituire beforeEach() con questo:

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

Se si utilizza spia invece di stub, allora la soluzione è non necessario. – TMG

+0

@TMG In realtà sto iniziando a chiedermi se la soluzione alternativa non causerà problemi con le chiamate a 'console.log()' create dai reporter che interferiscono con il conteggio delle chiamate di stub/spia. Probabilmente no, perché penserei che i giornalisti riportino solo dopo che il test è stato eseguito. In ogni caso, usare una spia è davvero una soluzione migliore. – robertklep

2

ignorando il fatto che si tratta di una funzione privata, vorrei prendere un paio di passi; rifatta il mio codice per una migliore separazione delle preoccupazioni e utilizza questa separazione con i duplicati dei test.

  • prendere tutti gli effetti collaterali all'esterno per i propri moduli (l'effetto collaterale qui sta scrivendo alla console):

    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}; 
    
  • utilizzare alcuni modulo proxy/spia, come proxyquire sostituire l'intero scrittore quando il test:

    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); 
        }); 
    }); 
    
Problemi correlati