gpt4 book ai didi

angularjs - 如何测试 Angular 装饰器功能

转载 作者:行者123 更新时间:2023-11-28 19:45:56 24 4
gpt4 key购买 nike

我在 Angular 中有一个装饰器,它将扩展 $log 服务的功能,我想测试它,但我没有找到执行此操作的方法。这是我的装饰器的 stub :

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!' 消息。但在我的测试中,我没有得到那个输出。

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

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

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) 中,初始版本是 @jakerella 提供的(大部分)未修改的代码(语法的小调整)。我尝试使用我可以从原始帖子中获得的相同依赖项。注意 tests.js:12-14:

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

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

一个解决方案是在该配置函数内部重新应用装饰器,正如您从 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 定义替换 $log 服务的debug 方法,导致后面调用MockNativeLog.debug.should。 be.called(1) 失败。 MockNativeLog.debug 方法不再是 chai.spy 提供的 spy 程序,因此匹配器将不起作用。

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

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

关于angularjs - 如何测试 Angular 装饰器功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22488056/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com