Этот фрагмент отлично работает с 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()')
Это хороший кандидат для использования 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://github.com/sinonjs/sinon/issues/1683#issuecomment -364794930
Чтобы сказать, я долгое время пытался написать исправление для этого, но безуспешно. Это кошмар значений this
. Основная проблема, похоже, заключается в том, что new
указанная здесь функция, по своей сути создает новый this
, тогда как thisValues[0]
(как используется в исходном сообщении) относится к this
создано new
в самом тесте (то есть var some = new window.SomeClass();
) - я знаю, очень запутанно.
По сути, исправить это означает попытаться использовать оба варианта - вызов new
абсолютно означает новый this
, но мы должны вызвать его дважды (то есть один в тесте OP и один в proxy-invoke.js
), чтобы удовлетворить ES6. Так что у вас всегда будет два this
es. Единственное, что я мог придумать, - это привязать функции из одного this
к другому, но это было слишком хакерским делом даже для этого и сломало несколько других вещей.
Я надеюсь, что вышеизложенное имеет смысл, пожалуйста, исправьте / запросите разъяснения. См. Здесь, чтобы узнать, что на самом деле делает ключевое слово new
- TLDR создает новый объект и делает его this
вне зависимости от контекста.
Во всяком случае, я заметил одну вещь: 911c498 (коммит, который привел к регрессии) не включает тест, охватывающий проблему, которую он решает, - требование использовать new
с классами ES6. Вероятно, это связано с тем, что параметры линтинга для тестов не позволяют использовать ключевое слово class
поскольку они предназначены только для ES5. У меня есть коммит, добавляющий тест, так что любое будущее исправление текущей проблемы не отменяет исправление в 911c498 - я могу PR, если есть интерес.
Самый полезный комментарий
Даже если он не часто используется или, по крайней мере, о нем редко сообщается, я бы хотел исправить эту регрессию.