I'm testing a service that uses another service for API calls, let's call this the data service. The data service is tested elsewhere, so I've abstracted it away with a simple implementation that contains empty functions; I'm returning data via a deferred object and Jasmine's spyOn syntax.
The trouble I'm finding with this approach is when the data is returned, it's not immediately available on the calling object, as it would be if I used $httpBackend. Aware I could just use $httpBackend, but I'd like to know if I've missed something (simple or otherwise) in this approach.
Example section of code I'm trying to test:
storeTheData = dataService.getSomeData();
storeTheData.$promise.then(function(data) {
/*this would work*/
console.log(data);
/*but this would not, when testing using $q*/
_.forEach(storeTheData, function(storedData) {
/*do something with each object returned*/
});
});
As a side note, I don't think the situation is helped by the ...$promise.then on another line, but ideally I wouldn't change the code (I'm providing test coverage to something written a while ago...)
Example of the test:
beforeEach(
...
dataService = {
getSomeData: function () { }
};
getSomeDataDeferred = $q.defer();
spyOn(dataService, "getSomeData").and.returnValue({$promise: getSomeDataDeferred.promise});
...
);
it(...
getSomeDataDeferred.resolve([{obj: "obj1"}, {obj: "obj2"}]);
$scope.$apply();
...
);
With the test described above, the console.log(data) would be testable as the data is accessible from being passed into the .then(). But the data is not immediately available from storeTheData, so storeTheData[0].obj would be undefined. On debug, I can see the data if I go through the promise that was attached to storeTheData via storeTheData.$$state.value
Like I said, I know I could use $httpBackend instead, but is there any way to do this with $q without changing the code under test?
Aucun commentaire:
Enregistrer un commentaire