对于自定义服务器端日志记录,我将象这样的angulars $ exceptionHandler包装在许多地方,包括stackoverflow和angular docs(在这里有变化,但它们基本上是在做同样的事情):

loggingModule.config(function ($provide) {
    $provide.decorator('$exceptionHandler', function ($delegate, ExceptionLoggingService) {
        return function () {
            // Call our own ExceptionLoggingService
            ExceptionLoggingService.apply(null, arguments);
            // Call the original
            $delegate.apply(null, arguments);
        };
    });
});


但是,这导致$ exceptionHandler在业力/茉莉花单元测试期间不会引发任何错误。

这可以通过使用this test taken from the angular docs来解决,当没有装饰模块时,它运行良好,但在以下情况下全部失败:

beforeEach(module('logging'));

describe('$exceptionHandlerProvider', function () {
    // testing standard behaviour of $exceptionHandler
    // see https://docs.angularjs.org/api/ngMock/service/$exceptionHandler
    it('should capture log messages and exceptions', function () {
        module(function ($exceptionHandlerProvider) {
            $exceptionHandlerProvider.mode('log');
        });

        inject(function ($log, $exceptionHandler, $timeout) {
            $timeout(function () {
                $log.log(1);
            });
            $timeout(function () {
                $log.log(2);
                throw 'banana peel';
            });
            $timeout(function () {
                $log.log(3);
            });
            expect($exceptionHandler.errors).toEqual([]);
            expect($log.assertEmpty());
            $timeout.flush();
            expect($exceptionHandler.errors).toEqual(['banana peel']);
            expect($log.log.logs).toEqual([[1], [2], [3]]);
        });
    });
});


知道如何解决此问题吗?也是check out this plunkr

我正在使用angular#1.3.14

最佳答案

$exceptionHandler中的ngMock函数具有指向数组的error属性。

装饰器返回的函数不具有该属性:

return function () {

  ExceptionLoggingService.apply(null, arguments);

  $delegate.apply(null, arguments);
};


因此,这将例如失败:

expect($exceptionHandler.errors).toEqual([]);


这是一个有望实现的实现:

app.config(function($provide) {
  $provide.decorator('$exceptionHandler', ['$delegate', 'ExceptionLoggingService',
    function($delegate, ExceptionLoggingService) {

      var decoratedExceptionHandler = function() {

        ExceptionLoggingService.apply(this, arguments);

        return $delegate.apply(this, arguments);
      };

      for (var key in $delegate) {

        if (!$delegate.hasOwnProperty(key)) continue;

        decoratedExceptionHandler[key] = $delegate[key];
      }

      return decoratedExceptionHandler;
    }
  ]);
});


注意,装饰时应始终确保执行此操作。 $exceptionHandler的实际实现现在可能没有任何属性,但是您永远不会知道将来是否会具有。 $templateRequest服务是您必须执行此操作的一个示例,因为该服务具有在内部用于使视图动画起作用的属性。

关于javascript - 装饰angularjs $ exceptionHandler时如何防止讨厌的副作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34319211/

10-13 01:53