I've got a Controller that uses a service that has a callback function on success.
Controller Function
itemCtrl.save = function () {
ItemService.save({ username: SessionService.getUsername() }, itemCtrl.item, function (res) {
$scope.$emit('UPDATE_ITEMS');
$modalInstance.close(res);
});
};
spec
it('should close the modal on successful save', function () {
spyOn(itemSrv, 'save').and.callFake(function () {
deferred = q.defer();
deferred.resolve();
return deferred.promise;
});
spyOn(modalInst, 'close').and.callThrough();
ItemCtrl.save();
scope.$digest();
expect(modalInst.close).toHaveBeenCalled();
});
When I run this test in karma is failing because the close function of the modalinstance is not called. I think the problem is on the spec description, because the functionality is working in the app. I have a few questions about this:
-- EDIT --
I've changed my service calls to make them handle results as promises:
itemCtrl.save = function () {
ItemService.save({ username: SessionService.getUsername() }, horas.trabajo).$promise.then(function (res) {
$scope.$emit('UPDATE_ITEMS');
$modalInstance.close(res);
});
};
I guess I'm not passing the tests because my service does not return a promise (it has a promise attribute which I'm calling to emit the event and close the modalInstance). But still I'm getting confused about how to return a promise using ng-resource.
My attempt to solve it was returning an object with a $promise attribute, which contains the promise that q provides.
spec
it('should close the modal on successful save', function () {
spyOn(itemSrv, 'save').and.callFake(function () {
deferred = q.defer();
deferred.resolve();
return {$promise: deferred.promise};
});
spyOn(modalInst, 'close').and.callThrough();
ItemCtrl.save();
scope.$digest();
expect(modalInst.close).toHaveBeenCalled();
});
You are confusing the concepts of promises and callbacks, but to get it to work as you currently have it you can use this:
spyOn(itemSrv, 'save').and.callFake(function (params, callback) {
callback({some: 'response'});
});
Callback
You pass in a function that will be called based upon a scenario
Promise
Get back an object which contains a method on it (then) which will call either the 1st param on success or the 2nd param on error
There is more to both, but this is a general overview.
Also, I'd suggest changing the save method in your service to return a promise rather than accepting a callback.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With