2013-08-30 4 views
11

내 웹 응용 프로그램에 대한 로깅 모듈을 nodejs에 만들고 있습니다. 내 모듈 terminal 올바른 메시지를 출력하는 mocha 사용하여 테스트 할 수 싶습니다. 나는 주변을 둘러 보았지만 이것을 확인하는 확실한 해결책을 찾지 못했습니다. 나는 찾았습니다모카 모니터 응용 프로그램 출력

process.stdout.on('data', function(){}) 

그러나 이것을 작동시키지 못했습니다. 아무도 조언을하나요?

답변

12

process.stdout은 읽을 수있는 스트림이 아니기 때문에 절대로 'data' 이벤트를 방출하지 않습니다. 호기심이 있다면 node stream documentation의 모든 내용을 읽을 수 있습니다.

내가 아는 한 process.stdout 또는 process.stderr을 연결하거나 캡처하는 가장 간단한 방법은 process.stdout.write을 원하는대로 수행하는 것입니다. 슈퍼 해키, 알아,하지만 테스트 시나리오에서 전 후크를 사용하여 걸쇠가 풀리지 않도록 할 수 있기 때문에 무해한 경우가 많습니다. 어쨌든 기본 스트림에 쓰기 때문에, 어쨌든 그것을 언 후크하지 않으면 세계의 끝이 아닙니다.

function captureStream(stream){ 
    var oldWrite = stream.write; 
    var buf = ''; 
    stream.write = function(chunk, encoding, callback){ 
    buf += chunk.toString(); // chunk is a String or Buffer 
    oldWrite.apply(stream, arguments); 
    } 

    return { 
    unhook: function unhook(){ 
    stream.write = oldWrite; 
    }, 
    captured: function(){ 
     return buf; 
    } 
    }; 
} 

이 같은 모카 테스트에서 사용할 수 있습니다 :

describe('console.log', function(){ 
    var hook; 
    beforeEach(function(){ 
    hook = captureStream(process.stdout); 
    }); 
    afterEach(function(){ 
    hook.unhook(); 
    }); 
    it('prints the argument', function(){ 
    console.log('hi'); 
    assert.equal(hook.captured(),'hi\n'); 
    }); 
}); 

는 여기에주의입니다 : 모카 기자가 표준 출력에 인쇄 할 수 있습니다. 예 (it('...',function(){})) 함수가 실행되는 동안은 알지 못하지만 예제 함수가 비동기 일 경우 문제가 발생할 수 있습니다. 내가 이것에 대해 더 알 수 있는지 알게 될거야.

11

나는 jjm의 대답을 시도했으며 내 프로그램 비동기 동작으로 인한 것으로 의심되는 문제가있었습니다.

sinon 라이브러리를 사용하는 github의 cli를 통해 해결책을 찾았습니다.

테스트하는 예제 코드 :

/* jshint node:true */ 
module.exports = Test1; 

function Test1(options) { 
    options = options || {}; 
} 


Test1.prototype.executeSync = function() { 
    console.log("ABC"); 
    console.log("123"); 
    console.log("CBA"); 
    console.log("321"); 
}; 

Test1.prototype.executeASync = function(time, callback) { 
    setTimeout(function() { 
    console.log("ABC"); 
    console.log("123"); 
    console.log("CBA"); 
    console.log("321"); 
    callback(); 
    }, time); 
}; 

그리고 모카 시험 :

/* jshint node:true */ 
/* global describe:true, it:true, beforeEach:true, afterEach:true, expect:true */ 

var assert = require('chai').assert; 
var expect = require('chai').expect; 
var sinon = require("sinon"); 

var Test1 = require("../test"); 

var test1 = null; 

describe("test1", function() { 
    beforeEach(function() { 
    sinon.stub(console, "log").returns(void 0); 
    sinon.stub(console, "error").returns(void 0); 
    test1 = new Test1(); 
    }); 

    afterEach(function() { 
    console.log.restore(); 
    console.error.restore(); 
    }); 

    describe("executeSync", function() { 
    it("should output correctly", function() { 
     test1.executeSync(); 

     assert.isTrue(console.log.called, "log should have been called."); 
     assert.equal(console.log.callCount, 4); 
     assert.isFalse(console.log.calledOnce); 
     expect(console.log.getCall(0).args[0]).to.equal("ABC"); 
     expect(console.log.getCall(1).args[0]).to.equal("123"); 
     expect(console.log.args[2][0]).to.equal("CBA"); 
     expect(console.log.args[3][0]).to.equal("321"); 
    }); 
    }); 

    describe("executeASync", function() { 
    it("should output correctly", function(done) { 
     test1.executeASync(100, function() { 
     assert.isTrue(console.log.called, "log should have been called."); 
     assert.equal(console.log.callCount, 4); 
     assert.isFalse(console.log.calledOnce); 
     expect(console.log.getCall(0).args[0]).to.equal("ABC"); 
     expect(console.log.getCall(1).args[0]).to.equal("123"); 
     expect(console.log.args[2][0]).to.equal("CBA"); 
     expect(console.log.args[3][0]).to.equal("321"); 
     done(); 
     }); 

    }); 
    }); 
}); 

는 비동기 호출 작업을 보여줍니다 나는 위의를 제공하고있어, 그것은 콘솔 및 오류를 모두 다룬다 출력 및 검사 방법이 더 유용합니다.

콘솔에 전달 된 내용을 얻는 두 가지 방법, console.log.getCall(0).args[0]console.log.args[0][0]을 제공했음을 유의해야합니다. 첫 x 째 매개 변수는 콘솔에 기록되는 행입니다. 적절한 것으로 생각하는 것을 자유롭게 사용하십시오.

+2

이것은 일반적인 Sinon 스텁 패턴을 활용하고 process.stdout 또는 무엇이든 캡처하는 것보다 더 즉각적으로 이해할 수 있기 때문에 더 나은 대답 인 것 같습니다. 그래도 될거야 ... – aendrew

+0

test-console은 @endrew에 대해 말하는 것을 수행하는 경량 라이브러리입니다. 여기에 나와있는 내 답변보기 – ianstarz

2

도움이되는 다른 두 라이브러리는 test-consoleintercept-stdout입니다. intercept-stdout을 사용하지 않았지만 test-console을 사용하여이를 수행 할 수 있습니다.

var myAsync = require('my-async'); 
var stdout = require('test-console').stdout; 

describe('myAsync', function() { 
    it('outputs something', function(done) { 
    var inspect = stdout.inspect(); 

    myAsync().then(function() { 
     inspect.restore(); 
     assert.ok(inspect.output.length > 0); 
     done(); 
    }); 
    }); 
}); 

참고 : 당신은 모카의 비동기 API를 사용해야합니다. 전화가 done()이면 모카의 테스트 메시징을 삼킬 것입니다.

관련 문제