2016-12-14 58 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/