angularjs – 如何测试角度装饰器功能

前端之家收集整理的这篇文章主要介绍了angularjs – 如何测试角度装饰器功能前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在Angular中有一个装饰器,它将扩展$log服务的功能,我想测试它,但我没有看到这样做的方法.这是我的装饰者的存根:
  1. angular.module('myApp')
  2. .config(function ($provide) {
  3.  
  4. $provide.decorator('$log',['$delegate',function($delegate) {
  5. var _debug = $delegate.debug;
  6. $delegate.debug = function() {
  7. var args = [].slice.call(arguments);
  8.  
  9. // Do some custom stuff
  10.  
  11. window.console.info('inside delegated method!');
  12. _debug.apply(null,args);
  13. };
  14. return $delegate
  15. }]);
  16.  
  17. });

请注意,这基本上覆盖了$log.debug()方法,然后在执行一些自定义操作后调用它.在我的应用程序中这是有效的,我看到’内部委托方法!’控制台中的消息.但在我的测试中,我没有得到那个输出.

我该如何测试我的装饰功能
具体来说,我如何注入我的装饰器,以便它实际装饰我的$log模拟实现(见下文)?

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

  1. describe('Log Decorator',function () {
  2. var MockNativeLog;
  3. beforeEach(function() {
  4. MockNativeLog = {
  5. debug: chai.spy(function() { window.console.log("\nmock debug call\n"); })
  6. };
  7. });
  8.  
  9. beforeEach(angular.mock.module('myApp'));
  10.  
  11. beforeEach(function() {
  12. angular.mock.module(function ($provide) {
  13. $provide.value('$log',MockNativeLog);
  14. });
  15. });
  16.  
  17. describe('The logger',function() {
  18. it('should go through the delegate',inject(function($log) {
  19. // this calls my mock (above),but NOT the $log decorator
  20. // how do I get the decorator to delegate the $log module??
  21. $log.debug();
  22. MockNativeLog.debug.should.have.been.called(1);
  23. }));
  24. });
  25. });
从附加的plunk( http://j.mp/1p8AcLT)开始,初始版本是@jakerella提供的(大部分)未触及的代码(对语法进行微调).我试图使用我可以从原始帖子中获得的相同依赖项.注意tests.js:12-14:
  1. angular.mock.module(function ($provide) {
  2. $provide.value('$log',MockNativeLog);
  3. });

这完全覆盖了本机$log服务,正如您所期望的那样,使用在测试because angular.mock.module(fn) acts as a config function for the mock module开始时提供的MockNativeLog实现.由于配置函数以FIFO顺序执行,因此该函数破坏了装饰的$log服务.

一种解决方案是在配置函数中重新应用装饰器,正如你可以从插件的第2版看到的那样(永久链接会很好,Plunker),tests.js:12-18:

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

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

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

  1. var MockNativeLog,MockDebug;
  2.  
  3. beforeEach(function () {
  4. MockNativeLog = {
  5. debug: MockDebug = chai.spy(function () {
  6. window.console.log("\nmock debug call\n");
  7. })
  8. };
  9. });

代码可能更容易阅读:

  1. MockDebug = chai.spy(function () {
  2. window.console.log("\nmock debug call\n");
  3. });
  4.  
  5. MockNativeLog = {
  6. debug: MockDebug
  7. };

这仍然不代表一个好的测试结果,只是一个健全性检查.在几个小时之后敲打你的“为什么不这个工作”问题之后,这是一种解脱.

请注意,我还将装饰器函数重构为全局范围,以便我可以在tests.js中使用它而无需重新定义它.更好的方法是使用$provider.value()重构一个适当的服务,但是这个任务已经留给了学生……还是一个比我自己懒的人. :d

猜你在找的Angularjs相关文章