从附加的 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