Promise.catch()在AngularJS单元测试中没有捕获异常

前端之家收集整理的这篇文章主要介绍了Promise.catch()在AngularJS单元测试中没有捕获异常前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在Typescript中为我的应用程序编写茉莉花单元测试,并通过Resharper运行它们.如果处理程序引发异常,它应该执行一个操作:
describe("Q Service Test",() => {
    var q: ng.IQService;
    var rootScope: ng.IRootScopeService;

    beforeEach(inject(($q,$rootScope) => {
        q = $q;
        rootScope = $rootScope;
    }));

    it("Caught exceptions are handled properly",() => {
        var state = 'ok';
        q.when(1)
            .then(() => {
                throw new Error("test exception");
            })
            .catch(() => {
                state = 'error';
            });

        rootScope.$digest();
        expect(state).toBe('error');
    });
});

但测试失败:

我的测试环境/工具有一些奇怪的行为,还是我错误地使用承诺机制?

你绝对使用promise机制不正确,抛出一个用户定义的throw语句不构成将其作为承诺拒绝正确.如 $q文件所述:

When comparing deferreds/promises to the familiar behavior of
try/catch/throw,think of reject as the throw keyword in JavaScript.
This also means that if you “catch” an error via a promise error
callback and you want to forward the error to the promise derived from
the current promise,you have to “rethrow” the error by returning a
rejection constructed via reject.

它们是类似但不是等效的,为了捕获用户定义的throw语句,你应该使用catch语句块.虽然$q的承诺应该只能抵挡被拒绝的承诺.因此,在您的情况下,返回拒绝的承诺是处理该过程的正确方式,而不是抛出用户定义的异常.

DEMO

JAVASCRIPT

describe('Q Service Test',function() {

  var $q,$rootScope;

  beforeEach(inject(function(_$q_,_$rootScope_) {
    $q = _$q_;
    $rootScope = _$rootScope_;
  }));

  it('Rejected promises are handled properly',function() {

    var state = 'ok';

    $q.when(1)
      .then(function() {
        return $q.reject('rejected');
      })
      .catch(function() {
        state = 'error';
      });

    $rootScope.$digest();
    expect(state).toBe('error');    

  });

});

更新:

您的代码在浏览器中以此方式行为的原因是因为Angular的$q实现在处理promise队列时使用try / catch语句块.当任何回调引发任何错误时,它会捕获错误本身,拒绝该异常作为拒绝的原因,之后使用$exceptionHandler来记录错误.我建议你简单地拒绝承诺.

由于单元测试的原因是因为$exceptionHandler的角度模拟实现与实际应用的$exceptionHandler不同.前者创建了具有不同模式的提供商,默认的角模式实现使用重启模式,其中转动抛出异常而不是记录它.如果要让单元测试的行为与默认应用程序的$exceptionHandler的方式相同,那么您可以将模式设置为“log”.

DEMO

JAVASCRIPT

describe('Q Service Test',$rootScope;

  beforeEach(module('ng',function($exceptionHandlerProvider) {
    $exceptionHandlerProvider.mode('log');
  }));

  beforeEach(inject(function(_$q_,_$rootScope_) {
    $q = _$q_;
    $rootScope = _$rootScope_;
  }));

  it('Caught exceptions are handled properly',function() {

    var state = 'ok';

    $q.when(1)
      .then(function() {
        throw new Error();
      })
      .catch(function() {
        state = 'error';
      });

    $rootScope.$digest();
    expect(state).toBe('error');    

  });

});

猜你在找的Angularjs相关文章