Reputation: 1042
I'm trying to test a service in Angular that uses $http, but after approx 5 seconds (the jasmine timeout) I'm getting:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
I've tried using $rootScope.$digest(), but that didn't seem to make any difference. The tests (and app code) are written in Typescript and the code runs fine in the actual app.
I'm not seeing an alert/log saying that the then() has run, but I did manage to get it alerting with a setTimeout() in the test (no app changes) but I was still getting errors.
Test code
var $httpBackend, orderSearchService;
beforeEach(inject((_$httpBackend_, _orderSearchService_) => {
$httpBackend = _$httpBackend_;
orderSearchService = _orderSearchService_;
$httpBackend.expectGET("http://testUrl/api/search/testquery");
$httpBackend.whenGET("http://testUrl/api/search/testquery").respond(200, "testData");
}));
it("can call $http and retrieve results",(done) => {
orderSearchService.search("testquery").then(promise => {
var results = promise.data;
alert(results);
expect(results).toBe("testData");
$httpBackend.flush();
done();
});
});
Excerpt from service:
public search(term: string): angular.IPromise<any> {
var result: angular.IPromise<any> = this.httpService.get("http://testUrl" + "/api/search/" + term)
.success((data: any) => { return data });
return result;
}
My understanding is that the test should be calling search(), and that Jasmine should wait for done() to be called.
Upvotes: 0
Views: 1866
Reputation: 7438
After translation to JavaScript it will be look like this (as $httpBackend.flush()
runs digest loop internally)
I have also extract query params to object to stop DRY violation
angular
.module('app', [])
.service('orderSearchService', function($http) {
this.search = function(term) {
return $http.get("http://testUrl" + "/api/search/" + term).success(function(data) {
return data;
})
}
});
describe('orderSearchService', function() {
var $httpBackend, orderSearchService;
beforeEach(module('app'));
beforeEach(inject(function(_$httpBackend_, _orderSearchService_) {
$httpBackend = _$httpBackend_;
orderSearchService = _orderSearchService_;
}));
it("can call $http and retrieve results", function() {
var query = {
q: 'testquery',
response: 'testData'
};
$httpBackend.expectGET(/http:\/\/testUrl\/api\/search/);
$httpBackend.whenGET(new RegExp('http://testUrl/api/search/' + query.q)).respond(200, query.response);
orderSearchService.search(query.q).then(function(promise) {
var results = promise.data;
expect(results).toBe(query.response);
});
$httpBackend.flush();
});
});
<link href="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" />
<script src="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-mocks.js"></script>
Upvotes: 1