2016-12-14 62 views
1

目前,我有一個讀取文件的函數。當我把與測試錯誤的ReadFile的回調之外,它的工作原理:如何在節點的FileSystem.readfile內部單元測試邏輯cb

var doWork = function(path) { 
    //throw new RangeError('blah'); // works, error is thrown 

    fs.readFile(path, 'utf-8', function(error, data) { 
     //etc.... logic.. etc.. 
     if(data.split('\n')[0] > x) 
      throw new RangeError('blah'); //does not work 
    }); 
} 

我的測試:

describe('my test suite', function(){ 
    it('should throw an error', function(){ 
     var func = function() { 
      doWork('my path'); 
     } 

     var err = new RangeError('blah'); 

     expect(func).to.throw(err); //no error is thrown if "throw" is inside readFile cb 
    }); 
}); 

結果:

AssertionError: expected [Function: func] to throw RangeError 
     at Context.<anonymous> (test.js:53:27) 
+0

https://www.joyent.com/node-js/production/design/errors – dm03514

回答

1

要異步處理錯誤,您可以使用回調或承諾來通知調用方發生錯誤。

我認爲這個問題是:

  • expect(func)
  • readFile收益率(因爲它是異步)回測試
  • 測試報告失敗

你可以改變呼叫簽名doWork接受作爲第二個參數的回調(通常將錯誤作爲第一個參數和結果傳遞)。


我個人會建議尋找到的承諾,因爲我認爲他們是更清潔尋找,並更容易理解/與工作。應該允許你繼續拋出,並註冊catch/error事件來處理異常。

0

在@dm03514關閉時,將您的文件讀取器邏輯設置爲承諾,因爲您無法直接異步測試引發。

// fileprocessor.js 
'use strict'; 

//imports 
var Promise = require('bluebird'); 
var fs = Promise.promisifyAll(require('fs')); 

module.exports = class FileProcessor { 
    constructor() { 

    } 

    process(path) { 
     var deferred = Promise.pending(); //like $q.deferred() in angular 

     fs.readFileAsync(path, 'utf8').then(content => { 
      //... etc... logic... etc... 
      if(content.split('\n')[0] > 10) deferred.reject(new RangeError('bad')); 

      //... etc.. more... logic 
      deferred.resolve('good'); 
     }).catch(error => deferred.reject(error)); 

     return deferred.promise; 
    } 
} 

然後在你的測試套件中。

//test.js 
'use strict'; 

var chai = require('chai'); 
var expect = chai.expect; 
var chaiAsPromised = require('chai-as-promised'); 
chai.use(chaiAsPromised); 
var FileProcessor = require('./fileprocessor.js'); 

describe('my test suite', function(){ 

    var func =() => { 
     return new FileProcessor().process('my path'); 
    } 

    it('should resolve with a value',() => { 
     return expect(func).should.eventually.equal('good'); 
    }); 

    it('should reject with an error',() => { 
     return expect(func).should.be.rejectedWith(RangeError); 
    }); 
}); 

看一看chai-as-promisedhttp://chaijs.com/plugins/chai-as-promised/