2015-11-30 27 views
2

我正在使用Mocha和Chai和一個節點項目,並想知道如何測試節點函數中的錯誤回調?如何在Node.js中測試錯誤回調

這裏是我想測試我的代碼示例:

savePlayer: function(player) { 

    var playerName = player.name; 

    modules.fs.writeFile('./Data/' + playerName + '.json', JSON.stringify(player), function (err) { 
     if (err) { 
     return console.log(err.message); 
     } 
    }); 
} 

這是我的測試:

describe("savePlayer", function() { 
    it("Should save the player in JSON, using thier name", function() { 

    var player = {name: "test" } 

    modules.data.savePlayer(player); 

    var playerFile = modules.fs.readFileSync('Data/test.json').toString('utf8'); 

    expect(playerFile).should.exist; 

    }); 
}); 

此經過,但我想全代碼覆蓋率。此行return console.log(err.message);未經測試,我不確定如何僞造錯誤並測試控制檯報告了錯誤。

+0

取決於你如何編寫代碼,你需要重新佈線它返回一個MOCH或者在你的'savePlayer'函數中注入模擬 –

+0

是核心API fs的測試嗎? – webduvet

回答

3

下面是使用sinonchai的註解例如:

var fs   = require('fs'); 
var sinon  = require('sinon'); 
var expect  = require('chai').expect; 
var savePlayer = require('your-module').savePlayer; 

describe('savePlayer', function() { 
    // We spy on `console.log()` calls. Spying means that calls to this function 
    // are recorded, and we can check to see if it, for instance, was called with 
    // particular arguments. 
    var consoleSpy = sinon.spy(console, 'log'); 

    // We stub `fs.writeFile()`. Stubbing means that calls to this function 
    // are taken over, and we can determine exactly how it should act. 
    var fsStub  = sinon.stub(fs, 'writeFile'); 

    // Before each test, the spy and stub are reset. 
    beforeEach(function() { 
    consoleSpy.reset(); 
    fsStub.reset(); 
    }); 

    // After _all_ tests, the original functions are restored. 
    after(function() { 
    consoleSpy.restore(); 
    fsStub.restore(); 
    }); 

    // Test #1: if `fs.writeFile()` fails, it should trigger a call to `console.log`. 
    it('should log an error when `fs.writeFile` fails', function() { 
    var msg = 'my test error'; 

    // Here we let `fs.writeFile()` call the callback with an error. 
    fsStub.yields(new Error(msg)); 

    // Call your function. 
    savePlayer({ name : 'xx' }); 

    // Check to make sure that `console.log()` is called with the same error message. 
    expect(consoleSpy.calledWith(msg)).to.be.true; 
    }); 

    // Test #2: when `fs.writeFile()` went okay, nothing should be logged. 
    it('should not log an error when `fs.writeFile` is okay', function() { 
    // As per Node convention, falsy first argument means 'no error'. 
    fsStub.yields(null); 

    // Call your function. 
    savePlayer({ name : 'xx' }); 

    // We expect that `console.log()` wasn't called. 
    expect(consoleSpy.called).to.be.false; 
    }); 

}); 
0

如果您在單元測試工作,你需要確保一切都被隔離。這意味着沒有第三方或後端連接。

所以你需要將所有的存根。

你的主模塊文件會像==>

savePlayer: function(player) { 

    var playerName = player.name; 

    modules.fs.writeFile('./Data/' + playerName + '.json', JSON.stringify(player), function (err) { 
     if (err) { 
     // throw error message 
     throw new Error(err.message); 
     } 
    }); 
} 

示例代碼==>

const fs = require('fs) 
const sinon = require('sinon') 

describe("savePlayer",() => { 
    it("Should save file successfully", done => { 

    // stub all external connections (your external file) 
    const fsStub = fs.stub(fs, 'writeFile') 

    // expect save success 
    fsStub.yields(null) 

    // declare param 
    const player = {name: "test" } 

    // execute function 
    modules.data.savePlayer(player) 

    // test 
    expect(fsStub.called).to.be.true 

    // clean 
    fsStub.restore(); 
    done(); 
    }); 

    it("Should get error", done => { 

    // stub all external connections (your external file) 
    const fsStub = fs.stub(fs, 'writeFile') 

    // expect error 
    fsStub.yields(new Error('SOME ERROR OCCURS')) 

    // declare param 
    const player = {name: "test" } 

    // execute function 
    try { 
     modules.data.savePlayer(player) 
    } catch(e) { 
     // test 
     expect(e.message).eql('SOME ERROR OCCURS'); 

     // clean 
     fsStub.restore(); 
     done(); 
    } 
    }); 
});