I'm testing an angular service using angular extended promises as one of its dependencies. It looks like this:
angular.module('main')
.service('MyService', ['_', '$q', 'DatabaseService',
function(_, $q, DatabaseService) {
function loadResources(resources) {
var resources = _.mapValues(resources, function(config, type) {
return DatabaseService.getByType(type)
.then(function(data) {
return index(type, data);
});
});
return $q.props(resources);
});
var service = {
loadResources: loadResources
};
return service;
}
])
;
I want to make a test for the loadResources function and for this I stub DatabaseService.getByType function. I'm using mocha, chai, sinon running on karma. My test looks like this:
describe('[Service] MyService', function() {
var MyService, DatabaseService, $q;
var databaseBrand = [...]; // My fixtures
beforeEach(function() {
module('myApp');
inject(function($injector) {
MyService = $injector.get('MyService');
DatabaseService = $injector.get('DatabaseService');
$q = $injector.get('$q');
sinon.stub(DatabaseService, 'getByType', function(type) {
var typeResources = databaseBrand.filter(function(resource) {
return resource.type === type;
});
return $q.resolve(typeResources);
});
});
});
afterEach(function() {
DatabaseService.getByType.restore();
});
it('loadResources method', function() {
var configTest = { resources: [...] }; // input test data
var promise = MyService.loadResources(configTest);
return promise.should.be.fulfilled
.then(function(brandResources) {
console.log('PROMISE RESOLVED');
expect(brandResources).to.be.an('object');
// Other expects
})
;
});
});
When I run the test I have this timeout:
PhantomJS 2.1.1 (Mac OS X 0.0.0) [Service] MyService loadResources method FAILED
timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
I have already seen some post when people suggest to use the .$apply() or $digest() of the rootScope to "force" the promise to be resolved. But the thing is that I'm a testing a service and I want to isolated it to test without any other wired behavior.
I have made modifications to recover the $rootScope during the beforeEach and to force the $digest within the afterEach and the log that I added in my test is shown (what is cool) but then I have some errors, attemping to request some resources that are not included in my scenario...
PhantomJS 2.1.1 (Mac OS X 0.0.0) [Service] MyService "after each" hook for "loadResources method" FAILED Unexpected request: GET /api/config No more request expected $httpBackend@bower_components/angular-mocks/angular-mocks.js:1211:90 sendReq@bower_components/angular/angular.js:10333:21 serverRequest@bower_components/angular/angular.js:10045:23 [native code] processQueue@bower_components/angular/angular.js:14567:30 bower_components/angular/angular.js:14583:39 $eval@bower_components/angular/angular.js:15846:28 $digest@bower_components/angular/angular.js:15657:36 $apply@bower_components/angular/angular.js:15951:31
Is there any way to avoid to use this $digest or $apply ? Why do I have to do this to allow $q.prop to resolve the promise if I'm within a service and not a controller ?
Thanks
Aucun commentaire:
Enregistrer un commentaire