0

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.

1
  • You've skipped calling $digest() method in unit test. Angular doesn't know when to execute .then() method Commented Jul 6, 2015 at 14:47

1 Answer 1

1

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>

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I made the changes back in the Typescript and I also had to remove an unused $provide in an earlier beforeEach(). I'm not sure why it was still broken with the $provide.
You called $httpBackend.flush() inside method that was inaccessible for Angular as then is executed after flush()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.