简体   繁体   中英

Testing catch promise in Jasmine and AngularJS

I have some code like this inside my component:

p.a().then(function(x) {
  vm.x = x;
  return p.b();
}).then(function(y) {
  if (!y) {
    return $q.reject(new Error('My Error'));
  }
  vm.y = y;
  return y;
}).catch(function(error) {
  log.error(error);
});

I'm able to test the success case fine:

it('is successful', function(done) {
  spyOn(p, 'a').and.returnValue($q.resolve('x'));
  spyOn(p, 'b').and.returnValue($q.resolve('y'));

  $ctrl = $componentController('myComponent', {
    $scope: $rootScope.$new()
  });

  p.a().then(function() {
    expect($ctrl.x).toEqual('x');
    return p.b();
  }).then(function() {
    expect($ctrl.y).toEqual('y');
    done();
  });

  $timeout.flush();
});

But I am not able to test the catch and assert the error:

it('fails', function(done) {
  spyOn(p, 'a').and.returnValue($q.resolve());
  spyOn(p, 'b').and.returnValue($q.resolve());

  $ctrl = $componentController('myComponent', {
    $scope: $rootScope.$new()
  });

  p.a().then(function() {
    return p.b();
  }).catch(function(error) {
    expect(error).toEqual(new Error('My Error'));
    done();
  });

  $timeout.flush();
});

All I get when I run the tests is:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

Which means the catch is not even running (I tried logging something to double check).

Any ideas what am I doing wrong?

Consider instead of using jasmine done feature to use $rootScope.$apply(); Buy doing this angular automatically runs the promises

Remember to put the following code to inject $rootScope in the tests:

var $rootScope;
   beforeEach(inject(function(_$rootScope_) {
      $rootScope=_$rootScope_.$new();
   }));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM