We use karma to unit test our angular services, these services contains $http calls, so we have a mocked $httpbackend in place so we can run the app without server and db. this works fine, a service can call $http("someurl?id=1234") and we get the right data back.
But when we try to do the same thing in unit tests, we can't get it to work, the promise never resolves, when it involves $http
The service:
getAllowedTypes: function (contentId) {
var deferred = $q.defer();
$http.get(getChildContentTypesUrl(contentId))
.success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for content id ' + contentId);
});
return deferred.promise;
}
The mocked $httpbackend
$httpBackend
.whenGET(mocksUtills.urlRegex('/someurl'))
.respond(returnAllowedChildren); //returns a json object and httpstatus:200
The test
it('should return a allowed content type collection given a document id', function(){
var collection;
contentTypeResource.getAllowedTypes(1234).then(function(result){
collection = result;
});
$rootScope.$digest();
expect(collection.length).toBe(3);
});
but collection is undefined, .then() is never called.
tried pretty much everything to get the promise to resolve, $rootScope.$apply(), $digest, $httpBacke.flush(), but nothing works
So mocked $httpBackend works when called from controllers in app, but not when services is called directly in karma unit tests
We will be looking out how Angular handle promises. A promise is an object that may produce a single value some time in the future: either a resolved value or a reason that it’s not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending. Make a new promise from the thenable.
Open your Angular project in your favorite text editor and then go to app.module.ts file and import HttpClientModule service. Then also register it inside the imports array. Next, go to the app.component.ts file. Here we will write the core logic to make the HTTP GET request and manage the response using the ES6 Promise in Angular.
Angular 11 Promises Example with HttpClient API. In this section, we are going to look at how to use Promises in Angular to manage the HTTP response asynchronously. Open your Angular project in your favorite code editor and then go to app.module.ts file and import HttpClientModule service. Then also register it inside the imports array.
As per the general term, a promise is a commitment or guarantee by someone to do or not do something. It goes the same with JavaScript promises, we define a promise object, and its provides the surety that it will return something in the future. A promise object works only once. Either It will be succeeded or failed, but it won’t work twice.
You should not need to digest twice, since $httpBackend.flush() calls digest itself. You have to make the call, call digest to resolve the request interceptors, the call flush.
Here is a working Plnkr: http://plnkr.co/edit/FiYY1jT6dYrDhroRpFG1?p=preview
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