Reputation: 1977
I am trying to create a unit test for a service call in my method. The unit test returns the following error:
TypeError: Unable to get property 'catch' of undefined or null reference
Controller method I am testing:
$scope.getAsset = function (id) {
if ($scope.id != '0') {
assetFactory.getAsset($scope.id)
.then(function (response) {
$scope.asset = response.data;
})
.catch(function (error) {
alertService.add('danger', 'Unable to load asset data: ' + error.statusText + '(' + error.status + '). Please report this error to the application administrator');
});
}
};
My unit test is as follows:
it('method getAsset() was called', function () {
var asset = { AssetId: 'TEST123' };
var spy = spyOn(assetFactory, 'getAsset').and.callFake(function () {
return {
then: function (callback) {
return callback(asset);
}
};
});
// call the controller method
var result = scope.getAsset();
// assert that it called the service method. must use a spy
expect(spy).toHaveBeenCalled();
});
When I remove the ".catch(function (error)" statement from my controller method, the test passes. It appears I have to implement the catch in my spy but I can't figure out how.
Upvotes: 4
Views: 4224
Reputation: 21829
I also had this problem, but the above solution couldn't help. My problem was a bit different. I was using a mock as preceding.
jasmine.createSpy('mockFunc()').and.callFake()
Then I changed it to as below with a call back function.
jasmine.createSpy('mockFunc()').and.callFake(function() { })
I know it sounds crazy, but this solved my issue. You can also give a try if you had done the same mistake.
Upvotes: 0
Reputation: 21278
The then
and catch
methods comes from the promise pattern which is implemented in AngularJS by the $q
service.
Your mocked (faked) method should also return a promise. The easiest way is to use $q.when(value)
. It creates promise which immediately resolves to given value
.
Try:
var response = {data: asset};
var spy = spyOn(assetFactory, 'getAsset').and.returnValue($q.when(response));
Of course, you need to inject $q
in your tests.
It's also worth to read How to unit-test promise-based code in Angular.
Upvotes: 3