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

2023-12-21

我正在 Typescript 中为我的应用程序编写 Jasmine 单元测试,并通过 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 https://docs.angularjs.org/api/ng/service/%24q文档:

当将 deferreds/promise 与熟悉的行为进行比较时 尝试/捕捉/抛出,思考reject as the throwJavaScript 中的关键字。 这也意味着如果您通过承诺错误“捕获”错误 回调并且您希望将错误转发到派生的承诺 当前的承诺,你必须通过返回一个来“重新抛出”错误 通过拒绝构造拒绝。

它们相似但不等同,要捕获用户定义的 throw 语句,您应该使用catch语句块。尽管$q承诺只应catch拒绝的承诺。因此,在您的情况下,返回被拒绝的承诺是处理流程的正确方法,而不是抛出用户定义的异常。

DEMO http://plnkr.co/edit/StJdi62SJQSBCaivbkym?p=preview

脚本语言

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');    

  });

});

UPDATE:

你的代码在浏览器中表现出这种行为的原因是因为 Angular 的$q实现使用try/catch处理 Promise 队列时的语句块。当任何回调抛出任何错误时,它会捕获错误本身,并以异常作为拒绝原因来拒绝它,然后使用$exceptionHandler记录错误。我建议您简单地返回拒绝的承诺。

至于单元测试这样做的原因是因为angular-mocks的实施$exceptionHandler https://docs.angularjs.org/api/ngMock/provider/%24exceptionHandlerProvider与实际应用有所不同$exceptionHandler https://docs.angularjs.org/api/ng/service/%24exceptionHandler。前者创建具有不同模式的提供程序,默认的 Angular-Mocks 实现使用rethrow模式反过来抛出异常而不是记录它。如果您想让单元测试的行为与默认应用程序的行为相同$exceptionHandler然后你可以将模式设置为'log'.

DEMO http://plnkr.co/edit/gGoYcTGXglSBN12UGmGw?p=preview

脚本语言

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

  var $q,
      $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');    

  });

});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Promise.catch() 在 AngularJS 单元测试中没有捕获异常 的相关文章

随机推荐