user1387717
user1387717

Reputation: 1049

karma jasmine servce promise does not resolve in unit test and $stateChangeStart

I need to have created the following unit test that relies on a promise in a service being resolved, but the finally() callback is never called. The promise works just fine in the real application. I have read in various places that I need to kick off a digest cycle but that doesn't work. I'm using ui-router and it just starts an $stateChangeStart request and tries to retrieve the template of the first state. (Hence the $httpBackend mock for that).

  var $rootScope;
  var scope;
  var $httpBackend;
  var FormulaValidator;
  var mockFunctionApiBaseUrl = 'http://localhost:5555';

  beforeEach(function() {
    module('ps', function($provide) {
        $provide.constant('functionApiBaseUrl', mockFunctionApiBaseUrl);
        $provide.value('identity', {
          getUsernameFromLocalStorage: function() {
            console.log('getting mock username from local storage');
            return 'BLAH';
          },
          verifyToken: function(token) {
            return true;
          }
        });
  });
  beforeEach(function(done) {
    inject(function(_$httpBackend_, _$rootScope_, _FormulaValidator_) {
      $httpBackend = _$httpBackend_;
      $rootScope = _$rootScope_;
      scope = $rootScope.$new();
      FormulaValidator = _FormulaValidator_;
      $httpBackend.expect('GET', mockFunctionApiBaseUrl + '/api/list/functions').respond(200, '{"MA": {}}');
      $httpBackend.expect('GET', '/0.1.1/json/assets.json').respond(200, '["AAPL US EQUITY"]');
      $httpBackend.expect('GET', '/null/templates/dashboard.html').respond(200, '<html></html>');
      done();
    })
  });

  afterEach(function() {
   $httpBackend.flush();
  });

  it('Basic Validation 1', function (done) {
    FormulaValidator.promise.finally(function () {
      console.log('FormulaValidator.spec.promise finally');
      var p = FormulaValidator.validateFormula('MA(AAPL US EQUITY, 30)');
      console.log('getFunctions:  ' + FormulaValidator.getFunctions().length);
      expect(p).toBe(true);
      done();
    });
    scope.$apply();
    //$rootScope.$digest();
  });

Upvotes: 0

Views: 282

Answers (1)

JB Nizet
JB Nizet

Reputation: 692023

An $http promise will only be resolved when you flush the $httpBackend.

Flushing it in afterEach() is too late: the point of flushing $httpBackend is to tell it: OK, now you're supposed to have received requests, send back the response so that the promise is resolved with what I've told you to send back when calling $httpBackend.expect().

Read more about it is the doc.

Upvotes: 1

Related Questions