问题
Here's how my function looks like.
var myFunc = function(){
return functionReturningaPromise()
.then(function(){
//success, doesn't matter what happens here
})
.catch(function(err){
//handle error here and then throw to handle higher
throw new Error('Error in my function');
})
}
I need the function to be this way to handle an error inside this function and then throw an error to handle on higher level. But i don't know how to test it with jasmine. I know how to control the promises for testing and my basic set up looks like this:
it('Should throw an error', inject(function(alert) {
var instance = instanceFactory.createInstance(someData);
var deferred = $q.defer();
spyOn(someFactory, 'someMethod').and.returnValue(deferred.promise);
//instance contains the throwing function above
instance.myFunc(otherData);
deferred.reject({data: '12 - error'});
$rootScope.$digest();
expect(instance.myFunc).toThrow();
}));
Obviously, the error is not found by jasmine. So how to test the error throw in this case
回答1:
$q
does not work well with native throw
, you should use $q
API to re-throw or create new errors inside promise chain. Some Q/A to read about it:
- Promise.catch() does not catch exception in AngularJS unit test
- Why can I not throw inside a Promise.catch handler?
- AngularJS - Promises rethrow caught exceptions
The solution will be to use return $q.reject('Error in my function')
instead of throw new Error('Error in my function');
.
But the open question is how to test it. Basically you can make use of promise chains and add one more .catch()
in test to check for error, and test is using Jasmine Async API:
it('should throw an error', function (done) {
// ----- use Jasmine async API -------^^^
var instance = instanceFactory.createInstance(someData);
var deferred = $q.defer();
spyOn(someFactory, 'someMethod').and.returnValue(deferred.promise);
// here we continue catching and check the error
var promise = instance.myFunc(otherData);
promise.catch(function (err) {
expect(err).toBe('Error in my function');
done();
});
deferred.reject({data: '12 - error'});
$rootScope.$digest();
});
Here is a working sample (open script.js
file in sidebar)
来源:https://stackoverflow.com/questions/33467485/how-to-test-that-an-angular-factory-function-using-a-promise-is-throwing-an-erro