Reputation: 409
Currently, I have a function that reads a file. When I throw and test for an error outside of the readfile callback, it works:
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
});
}
My tests:
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
});
});
Results:
AssertionError: expected [Function: func] to throw RangeError
at Context.<anonymous> (test.js:53:27)
Upvotes: 1
Views: 864
Reputation: 5557
Going off @dm03514, set your file reader logic as a promise since you can't directly test throws asynchronously.
// 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;
}
}
Then in your test suites.
//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);
});
});
Have a look at chai-as-promised
: http://chaijs.com/plugins/chai-as-promised/
Upvotes: 0
Reputation: 55972
To handle errors asynchronously, you could use a callback, or promise, to notify the caller that an error occurs.
I think the issue is:
expect(func)
is calledreadFile
yields (because it's async) back to the testYou could change the call signature of doWork
to accept a callback (conventionally passed error as a first argument and a result) as a second argument.
I personally would recommend looking into promises, as I think that they are much cleaner looking, and easier to understand/work with. The should allow you to continue to throw, and to register an catch/error event to handle the exception.
Upvotes: 1