如何测试角度装饰器功能

2024-01-26

我在 Angular 中有一个装饰器,它将扩展 $log 服务的功能,我想测试它,但我没有找到实现此目的的方法。这是我的装饰器的存根:

angular.module('myApp')
  .config(function ($provide) {

    $provide.decorator('$log', ['$delegate', function($delegate) {
      var _debug = $delegate.debug;
      $delegate.debug = function() {
        var args = [].slice.call(arguments);

        // Do some custom stuff

        window.console.info('inside delegated method!');
        _debug.apply(null, args);
      };
      return $delegate
    }]);

  });

请注意,这基本上覆盖了$log.debug()方法,然后在完成一些自定义操作后调用它。在我的应用程序中,这有效,我看到'inside delegated method!'控制台中的消息。但在我的测试中我没有得到该输出。

我如何测试我的装饰器功能?
具体来说,我如何注入我的装饰器,使其真正装饰我的$log模拟实现(见下文)?

这是我当前的测试(摩卡/柴,但这并不真正相关):

describe('Log Decorator', function () {
  var MockNativeLog;
  beforeEach(function() {
    MockNativeLog = {
      debug: chai.spy(function() { window.console.log("\nmock debug call\n"); })
    };
  });

  beforeEach(angular.mock.module('myApp'));

  beforeEach(function() {
    angular.mock.module(function ($provide) {
      $provide.value('$log', MockNativeLog);
    });
  });

  describe('The logger', function() {
    it('should go through the delegate', inject(function($log) {
      // this calls my mock (above), but NOT the $log decorator
      // how do I get the decorator to delegate the $log module??
      $log.debug();
      MockNativeLog.debug.should.have.been.called(1);
    }));
  });
});

从附加的 plunk (http://j.mp/1p8AcLT http://j.mp/1p8AcLT),初始版本是@jakerella 提供的(大部分)未修改的代码(对语法进行了细微调整)。我尝试使用从原始帖子中得出的相同依赖项。笔记tests.js:12-14:

angular.mock.module(function ($provide) {
    $provide.value('$log', MockNativeLog);
});

这完全覆盖了原生$log正如您所期望的那样,服务MockNativeLog测试开始时提供的实现because angular.mock.module(fn)充当模拟模块的配置函数 http://j.mp/1p8G3AS。由于配置函数按照 FIFO 顺序执行,因此该函数会破坏装饰的$log服务。

一种解决方案是重新应用装饰器inside该配置函数,正如您从 plunk 的版本 2 中看到的那样(永久链接会很好,Plunker),tests.js:12-18:

angular.mock.module('myApp', function ($injector, $provide) {
    // This replaces the native $log service with MockNativeLog...
    $provide.value('$log', MockNativeLog);
    // This decorates MockNativeLog, which _replaces_ MockNativeLog.debug...
    $provide.decorator('$log', logDecorator);
});

然而,这还不够。装饰器@jakerella 定义replaces the debug的方法$log服务,导致稍后调用MockNativeLog.debug.should.be.called(1)失败。方法MockNativeLog.debug不再是由提供的间谍chai.spy,所以匹配器将不起作用。

相反,请注意我在中创建了一个额外的间谍tests.js:2-8:

var MockNativeLog, MockDebug;

beforeEach(function () {
    MockNativeLog = {
        debug: MockDebug = chai.spy(function () {
            window.console.log("\nmock debug call\n");
        })
    };
});

该代码可能更容易阅读:

MockDebug = chai.spy(function () {
    window.console.log("\nmock debug call\n");
});

MockNativeLog = {
    debug: MockDebug
};

这仍然不代表良好的测试结果,只是一个健全性检查。在花了几个小时思考“为什么这行不通”的问题后,这让你松了口气。

请注意,我另外将装饰器函数重构到全局作用域中,以便我可以在tests.js无需重新定义它。更好的方法是重构为适当的服务$provider.value(),但这项任务已作为练习留给学生......或者比我不那么懒的人。 :D

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

如何测试角度装饰器功能 的相关文章

随机推荐