如何使用sinon窥探继承的函数?
如果我有-
class Parent{
constructor(){}
foo(){
//do foo
}
}
class Child extend Parent{
constructor(){
super();
}
}
const childSpy = sinon.spy(Child.prototype, 'foo')
const parentSpy = sinon.spy(Parent.prototype, 'foo')
new Child().foo();
expect(childSpy).to.have.been.called; //false
expect(parentSpy).to.have.been.called; //true我做错了什么?
上面的示例是我的代码的简化版本,在实际代码中,我无法访问Child或Parent类的实例
发布于 2018-03-27 04:23:54
因此,我尝试了一下,得到了与您列出的结果不同的结果。在我的例子中,调用的是childSpy,而不是parentSpy,考虑到sinon的工作方式,这是我所期望的。所以我假设你在你的帖子里把它们弄混了,然后从那里开始。
这里发生的事情有点微妙,有点取决于sinon在物体上创建间谍时实际做了什么的知识。
执行此行时:
const childSpy = sinon.spy(Child.prototype, 'foo')Sinon首先在Child.prototype上访问一个名为foo.的属性,该属性实际上在Child.prototype上并不存在,因此JavaScript沿着原型链向上移动到Parent.prototype,,在那里它确实找到了这样的属性。
因此,sinon获得了对存储在Parent.prototype.foo中的原始函数的引用。它将此函数包装在间谍程序中,然后将其作为Child.prototype.foo分配给Child.prototype。
这里的奇怪之处在于,Child.prototype以前没有自己的对原始foo函数的引用,但现在它有了,这就是当您在Child的实例上调用foo时将调用的引用。
执行此行时:
const parentSpy = sinon.spy(Parent.prototype,'foo')
Sinon访问Parent.prototype.foo上的函数,将其包装在间谍中,并在其上分配间谍。这看起来应该会影响间谍在Child.prototype.foo中包装的功能,但事实并非如此,这里的间谍仍然包装着原始的Parent.prototype.foo。
您可能会想到颠倒间谍创建语句的顺序来尝试绕过这一点,但您会发现sinon不允许这样做。你不能包装一个已经映射的方法。也就是说,如果某个对象已经是间谍,则尝试使用sinon来“监视该间谍”将抛出。这是有充分理由的,尽管我相信在这种情况下这看起来很令人沮丧。
你不能访问你的类的实例,这看起来很奇怪,但是如果你真的必须这样做,那么解决这个问题的一种方法就是给子类提供它自己的foo方法。它所需要做的就是在super上使用相同的签名调用相同的方法:
class Parent{
constructor(){}
foo(){
//do foo
}
}
class Child extend Parent{
constructor(){
super();
}
foo(...args){
return super.foo(...args)
}
}
const childSpy = sinon.spy(Child.prototype, 'foo')
const parentSpy = sinon.spy(Parent.prototype, 'foo')
new Child().foo();
expect(childSpy).to.have.been.called;
expect(parentSpy).to.have.been.called;这样做将使您的childSpy包装Child.prototype.foo,它将调用Parent.prototype.foo在被调用时恰好是什么值。
发布于 2018-01-11 23:31:41
你最好试着窥探具体的对象,而不是类。
例如:
const expect = require('chai').expect;
const sinon = require('sinon');
describe('Some', () => {
it('one', () => {
class Parent {
constructor() { }
foo() {
//do foo
}
}
class Child extends Parent{
constructor() {
super();
}
}
const child = new Child();
const childSpy = sinon.spy(child, 'foo');
child.foo();
expect(childSpy.called).to.be.true; //true
});
});希望这能有所帮助。
https://stackoverflow.com/questions/48210221
复制相似问题