首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sinon窥探继承函数

Sinon窥探继承函数
EN

Stack Overflow用户
提问于 2018-01-11 23:11:14
回答 2查看 1.1K关注 0票数 1

如何使用sinon窥探继承的函数?

如果我有-

代码语言:javascript
复制
    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

我做错了什么?

上面的示例是我的代码的简化版本,在实际代码中,我无法访问ChildParent类的实例

EN

回答 2

Stack Overflow用户

发布于 2018-03-27 04:23:54

因此,我尝试了一下,得到了与您列出的结果不同的结果。在我的例子中,调用的是childSpy,而不是parentSpy,考虑到sinon的工作方式,这是我所期望的。所以我假设你在你的帖子里把它们弄混了,然后从那里开始。

这里发生的事情有点微妙,有点取决于sinon在物体上创建间谍时实际做了什么的知识。

执行此行时:

代码语言:javascript
复制
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上使用相同的签名调用相同的方法:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2018-01-11 23:31:41

你最好试着窥探具体的对象,而不是类。

例如:

代码语言:javascript
复制
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    

  });
});

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48210221

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档