Reputation: 8875
I have a factory that uses a promise to resolve a json file. It should only resolve this file the first time and return the result when called again.
Here is the factory
app.factory('getServerConfig', function ($q, $http, serverConfig) {
return function (fileName) {
var deferred = $q.defer();
if (serverConfig.loaded) {
deferred.resolve("alreadyLoaded");
} else {
$http.get(fileName).then(function (result) {
serverConfig.setConfig(result.data);
deferred.resolve("loaded");
}, function (result) {
deferred.reject();
});
}
return deferred.promise;
};
})
And how I test it :
it('should say hallo to the World', inject(function(getServerConfig) {
var promiseResult;
getServerConfig("server-config.json").then(function (result) {
promiseResult = result;
});
rootScope.$apply();
expect(promiseResult).toBe('loaded');
}));
Unfortunately, it looks likes promiseResult is never set. Here is a plunker with the code : http://plnkr.co/edit/uRPCjuUDkqPRAv07G5Nx?p=preview
Upvotes: 2
Views: 3148
Reputation: 23394
The problem is that $httpBackend demands a flush()
(take a look at Flushing HTTP requests), so you can mimic $http
asynchronous behavior in your test.
To solve it, store a reference of $httpBackend
(or inject it again) and call $httpBack.flush() after the request has been made.
Look:
it('should say hallo to the World', inject(function(getServerConfig, $httpBackend) {
var promiseResult;
getServerConfig("server-config.json").then(function (result) {
promiseResult = result;
});
$httpBackend.flush();
expect(promiseResult).toBe('loaded');
}));
If you gonna use $httpBackend
in most of your specs, consider storing it in a local variable, and set it in beforeEach
.
Upvotes: 3