如何使用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
类的实例
答案 0 :(得分:1)
所以,我试过这个并收到了与你列出的不同的结果。在我的情况下,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
分配给Child.prototype.foo
。
这里的奇怪之处在于Child.prototype
之前没有自己对原始foo
函数的引用,但现在它已经引用了, 现在将被调用当您在foo
。
Child
时
执行此行时:
const parentSpy = sinon.spy(Parent.prototype,'foo')
Sinon访问Parent.prototype.foo
处的函数,将其包装在间谍中,并将间谍分配给它。这似乎应该影响Child.prototype.foo
间谍包裹的功能,但事实并非如此。位于那里的间谍仍在包裹原始 Parent.prototype.foo
。
你可能会翻转你的间谍创作语句的顺序来试图解决这个问题,但你会发现sinon不允许这样做。您无法包装已映射的方法。即如果某事已经是间谍,试图使用sinon来“窥探间谍”就会抛出。这是有充分理由的,但我确信在这种情况下看起来很令人沮丧。
您无法访问类的实例似乎很奇怪,但如果您真的必须以这种方式执行操作,那么解决此问题的方法之一就是为Child类提供自己的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
恰好在调用它时的值。
答案 1 :(得分:0)
你最好试着窥探具体的对象而不是类。
例如
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
});
});
希望得到这个帮助。