如何在节点的FileSystem.readfile cb中单元测试逻辑

时间:2016-12-14 03:02:35

标签: javascript node.js unit-testing chai fs

目前,我有一个读取文件的功能。当我抛出并测试readfile回调之外的错误时,它可以工作:

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)

2 个答案:

答案 0 :(得分:1)

要异步处理错误,您可以使用回调或承诺来通知调用方发生错误。

我认为问题是:

  • - busybox top: CPU% = s->pcpu/sum(s->pcpu) * busy_cpu_ticks/total_cpu_ticks (pcpu is delta of sys+user time between samples) - procps-ng top: CPU% = s->pcpu/total_cpu_ticks 被称为
  • expect(func)收益(因为它是异步的)回到测试
  • 测试报告失败

您可以将readFile的调用签名更改为接受回调(通常将错误作为第一个参数和结果)作为第二个参数。

我个人会建议调查承诺,因为我认为它们更清晰,更易于理解/使用。应该允许你继续抛出,并注册一个catch / error事件来处理异常。

答案 1 :(得分: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/