你必须理解打字脚本和间谍活动背后的机制.
首先是打字脚本...
我忽略了class Parent()
个额外的帕伦.
Typescript在幕后使用原型继承.因此,原型将引用的属性从"基类"复制到新类.这就是for
循环在__extends()
函数中所做的.
这是您的打字脚本翻译成的ES5代码:
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Parent = (function () {
function Parent() {
}
Parent.prototype.buyFood = function () {
// buy food
};
return Parent;
}());
var Husband = (function (_super) {
__extends(Husband, _super);
function Husband() {
return _super.apply(this, arguments) || this;
}
Husband.prototype.makeDinner = function () {
_super.prototype.buyFood.call(this);
// make dinner;
};
return Husband;
}(Parent));
你可以用这个Typescript playground来翻译打字脚本.
super
表达式调用父类的buyFood()
方法,而不是"继承"Husband
的方法.
看到线了吗
_super.prototype.buyFood.call(this);
并遵循_super
参考.
现在茉莉花间谍...
间谍将用充当代理的间谍函数替换传递对象的命名函数.该代理现在可以跟踪调用,并根据编程行为控制是调用原始函数、伪函数、返回值还是什么都不做(默认).
very简化版spyOn()
可能是这样的:
function spyOn(obj, fn) {
var origFn = obj[fn],
spy = function() {
spy.calls.push(arguments);
};
spy.calls = [];
obj[fn] = spy;
}
不过,actual spy method美元要复杂得多.
你的台词
spyOn(husband, 'buyFood');
实际上会用间谍取代Husband
年第instance期中的方法.但是,由于代码调用基类(父原型)的引用,所以它与您刚才替换的函数不同.
解决方案
您应该调用this
引用的方法
class Husband extends Parent {
makeDinner() {
// call byFood() via this
this.buyFood();
}
}
... 或者监视父原型(super
):
it('Should make a good dinner', () => {
spyOn(Parent.prototype, 'buyFood');
husband.makeDinner();
expect(Parent.prototype.buyFood).toHaveBeenCalled();
}