Sinon: 监视构造函数时间谍的thisValue不指向实例

创建于 2018-02-09  ·  10评论  ·  资料来源: sinonjs/sinon

此代码段在Sinon 2.0.0上正常工作,但在Sinon 4.2.2上失败:

it('returns correct thisValue', function() {
    window.SomeClass = function() {
        this.counter = 0;
        this.inc = function() {
            this.counter++;
        };
        this.getCounter = function() {
            return this.counter;
        };
    };

    var spy = sinon.spy(window, 'SomeClass');
    var some = new window.SomeClass();
    some.inc();

    expect(spy.thisValues[0].counter).toEqual(1);
    expect(spy.thisValues[0].getCounter()).toEqual(1);
    some.inc();
    expect(spy.thisValues[0].counter).toEqual(2);
    expect(spy.thisValues[0].getCounter()).toEqual(2);
});

看起来thisValues[0]对象是一个代理,并不引用some的实际实例。

这是Sinon 4.2.2的错误:

Expected undefined to equal 1
TypeError: undefined is not a function (evaluating 'spy.thisValues[0].getCounter()')
Bug Medium Help wanted Regression hacktoberfest pinned

最有用的评论

即使它不常用,或者至少不常用,我也希望修复此回归问题。

所有10条评论

这是使用git bisect来确定何时更改行为的一个很好的选择,这可能会为更改是否是有意的(功能)或错误(错误)提供一些线索。

将提供的示例@ PVince81转换成可用于git bisect run的小型测试脚本,应该并不难。

如果您不知道如何使用git bisect ,那么这是升级的绝佳机会!

http://www.marclittlemore.com/how-to-find-bugs-using-git-bisect-with-this-easy-guide/

哦,我喜欢平分秋色! 我会照顾的..

我们去了:911c498dc14dc4034ba019526bf58f8b24d77da0间谍通过与new (#1626)的呼叫传递

感谢您这样做,@ PVince81! 一个修复程序可能还希望检查#1265,因为它涉及需要进行哪些更改以支持构造函数监视。

如果未使用new创建对象,则将调用此方法thisValue以及扩展名thisValues 。 相反,使用new时调用的方法将保持thisValue不变。

考虑到我们的代码只有一个用法,所以我很想走捷径并更改触发此操作的单个测试,因为我没有时间把头放在sinon的内部并且感觉不合格进行潜在的重大更改

因为似乎没有多少人抱怨这个问题,所以也许人们通常不以这种方式进行测试,并且修复不值得(只是观察,由维护者决定)

即使它不常用,或者至少不常用,我也希望修复此回归问题。

遇到相同的问题,是否有解决此问题的计划?

@ ivan-zakharchuk如果没有人自愿参加,那就没有计划,没有。 如果您要修复此问题,则可以采取自然的下一步;-)

这是有问题的提交: https :

只是说,我花了很长时间尝试为此编写一个修复程序,但是没有成功。 这是this值的噩梦。 核心问题似乎是new此处提供的功能固有地创建了一个全新的this ,而thisValues[0] (如原始文章中所用)是指thisnew在测试本身中创建的this (即var some = new window.SomeClass(); )-我知道这非常令人困惑。

从本质上讲,解决此问题意味着尝试同时使用两种方法-调用new绝对意味着新的this ,但是我们必须调用两次(即,在OP测试中一次,在proxy-invoke.js )来满足ES6。 因此,您总是要得到两个this es。 我唯一能想到的就是将功能从一个this绑定到另一个,但是即使如此,也太过分了,还打破了其他一些东西。

我希望以上说明是合理的,请随时纠正/要求澄清。 有关new关键字实际作用的信息,请参见此处-TLDR会创建一个新对象,并使其成为this ,无论上下文如何。

无论如何,我确实注意到的一件事是911c498(引入回归的提交)不包含涵盖其解决的问题的测试-将new与ES6类一起使用的要求。 这可能是因为测试的linting选项不允许class关键字,因为它们仅适合ES5。 我提交了一个添加测试的提交,以便将来针对当前问题的任何修复都不会取消修复911c498中的修复-如果有兴趣,我可以进行PR。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

fearphage picture fearphage  ·  3评论

zimtsui picture zimtsui  ·  3评论

stephanwlee picture stephanwlee  ·  3评论

JakobJingleheimer picture JakobJingleheimer  ·  3评论

stevenmusumeche picture stevenmusumeche  ·  3评论