如何测试角装饰功能 [英] How to test angular decorator functionality

查看:195
本文介绍了如何测试角装饰功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个角装饰就是要扩大$日志服务的功能,我想测试它,但我不明白的方式来做到这一点。这里是我的装饰器存根:

angular.module('对myApp')
  的.config(函数($提供){    $ provide.decorator('$日志',['$委托',函数($代表){
      VAR _debug = $ delegate.debug;
      $ delegate.debug =功能(){
        变参= [] .slice.call(参数);        //做一些定制的东西        window.console.info('内委托的方法!');
        _debug.apply(NULL,参数);
      };
      返回$代表
    }]);  });

注意,这个基本上覆盖 $ log.debug()方法,然后做一些定制的东西后调用它。在我的应用程序该控制台的作品,我看到的由内委托的方法!消息。但在我的测试中,我没有得到的输出。

如何测试我的装饰功能?? 结果
具体来说,我怎么可以注入我的装饰,使得它实际上装饰我的 $日志模拟实现(见下文)?

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

描述(日志装饰',函数(){
  VAR MockNativeLog;
  beforeEach(函数(){
    MockNativeLog = {
      调试:chai.spy(函数(){window.console.log(\\ nmock调试通话\\ n);})
    };
  });  beforeEach(angular.mock.module('对myApp'));  beforeEach(函数(){
    angular.mock.module(函数($提供){
      $ provide.value('$日志,MockNativeLog);
    });
  });  描述('记录仪',函数(){
    它('应该通过委托,注入(函数($日志){
      //这个调用我的模拟(上图),但不是$日志装饰
      //我怎么装饰委派$日志模块?
      $ log.debug();
      (1)MockNativeLog.debug.should.have.been.called;
    }));
  });
});


解决方案

从连接的普拉克( http://j.mp / 1p8AcLT ),最初的版本是(大部分)触及$ C $由@jakerella(语法小的调整)提供℃。我试图用我可以从原来的职位产生相同的依赖关系。注 tests.js:12-14

angular.mock.module(函数($提供){
    $ provide.value('$日志,MockNativeLog);
});

这完全覆盖本机 $日志服务,如你所料,与所提供的 MockNativeLog 实施在开始测试因为 angular.mock.module(FN)充当对于模拟模块配置功能。由于配置功能FIFO顺序执行,此功能则会覆盖装饰 $日志服务。

一个解决办法是重新申请装饰的 的内部的配置功能,您可以从普拉克第2版看到(永久链接将是不错,Plunker),测试.js文件:12-18

angular.mock.module('对myApp',函数($喷油器,提供$){
    //这替换MockNativeLog本地$日志服务...
    $ provide.value('$日志,MockNativeLog);
    //这个装饰MockNativeLog,这_replaces_ MockNativeLog.debug ...
    $ provide.decorator('$日志,logDecorator);
});

这是不够的,但是。装饰@jakerella定义的替换的在 $登录服务调试方法,导致后来打电话给 MockNativeLog.debug.should.be.called(1)失败。该方法 MockNativeLog.debug 不再受 chai.spy 提供的间谍,所以匹配器将无法工作。

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

VAR MockNativeLog,MockDebug;beforeEach(函数(){
    MockNativeLog = {
        调试:MockDebug = chai.spy(函数(){
            window.console.log(\\ nmock调试通话\\ n);
        })
    };
});

这code可能是更容易阅读:

MockDebug = chai.spy(函数(){
    window.console.log(\\ nmock调试通话\\ n);
});MockNativeLog = {
    调试:MockDebug
};

和这仍然没有重新present一个良好的测试结果,进行仔细的检查。那撞你的头靠在后,我就放心了为什么不这项工作了几个小时的问题。

请注意,我还重构了装饰功能为在全球范围内,这样我可以在 tests.js 使用它,而无需重新定义它。更好的将是重构为一个适当的服务 $ provider.value(),但该任务已经被作为一个练习的学生......或者有人小于懒我。 :D

I have a decorator in Angular that is going to extend the functionality of the $log service and I would like to test it, but I don't see a way to do this. Here is a stub of my decorator:

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
    }]);

  });

Notice that this basically overrides the $log.debug() method, then calls it after doing some custom stuff. In my app this works and I see the 'inside delegated method!' message in the console. But in my test I do not get that output.

How can I test my decorator functionality??
Specifically, how can I inject my decorator such that it actually decorates my $log mock implementation (see below)?

Here is my current test (mocha/chai, but that isn't really relevant):

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

解决方案

From the attached plunk (http://j.mp/1p8AcLT), the initial version is the (mostly) untouched code provided by @jakerella (minor adjustments for syntax). I tried to use the same dependencies I could derive from the original post. Note tests.js:12-14:

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

This completely overrides the native $log Service, as you might expect, with the MockNativeLog implementation provided at the beginning of the tests because angular.mock.module(fn) acts as a config function for the mock module. Since the config functions execute in FIFO order, this function clobbers the decorated $log Service.

One solution is to re-apply the decorator inside that config function, as you can see from version 2 of the plunk (permalink would be nice, 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);
});

That's not enough, however. The decorator @jakerella defines replaces the debug method of the $log service, causing the later call to MockNativeLog.debug.should.be.called(1) to fail. The method MockNativeLog.debug is no longer a spy provided by chai.spy, so the matchers won't work.

Instead, note that I created an additional spy in tests.js:2-8:

var MockNativeLog, MockDebug;

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

That code could be easier to read:

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

MockNativeLog = {
    debug: MockDebug
};

And this still doesn't represent a good testing outcome, just a sanity check. That's a relief after banging your head against the "why don't this work" question for a few hours.

Note that I additionally refactored the decorator function into the global scope so that I could use it in tests.js without having to redefine it. Better would be to refactor into a proper Service with $provider.value(), but that task has been left as an exercise for the student... Or someone less lazy than myself. :D

这篇关于如何测试角装饰功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆