Переход на 2.0
В 2.0 поменялось поведение methodsToSpyOn, и спаи методов теперь создаются лениво. Большинству проектов менять ничего не нужно. В худшем случае вы переименуете одну опцию:
- createSpyFromClass(ApiService, { methodsToSpyOn: ['get', 'post'] }); // 1.x: только эти два
+ createSpyFromClass(ApiService, { onlyMethodsToSpyOn: ['get', 'post'] }); // 2.x: только эти дваЧто проверить
- Найдите
methodsToSpyOn. Если спека рассчитывает, что спаями станут только перечисленные методы, переименуйте опцию вonlyMethodsToSpyOn. Подробно — раздел 1. - Найдите
Object.getOwnPropertyDescriptor(...).valueна спае. Если спека читает его до вызова метода, передайте{ lazySpies: false }. Подробно — раздел 2. - Больше ничего не меняется.
Зачем обновляться
Числа взяты из настоящих проектов, а не из бенчмарка.
| Что вы получаете | Измерено |
|---|---|
methodsToSpyOn больше не убирает спаи. В 1.x список из двух методов выбрасывал все остальные, и тест падал глубоко в конструкторе компонента. | В одном перенесённом компоненте падало 147 тестов из 147, стало 4. Два независимых проекта обходили эту опцию 739 и 572 раза. |
| Спаи методов ленивые во всех фабриках. Метод становится спаем, когда тест впервые к нему обращается. | 2 000 спаев класса с 40 методами, тест трогает два: 257 мс → 27 мс, 425 МБ → 35 МБ. В девять раз быстрее, в двенадцать раз меньше памяти. |
Предупреждение о неизвестном методе срабатывает там, где оно полезно. Теперь оно проверяет onlyMethodsToSpyOn, где опечатка теряет спай. | — |
Что изменилось
1. methodsToSpyOn дополняет, а не ограничивает
В 1.x явный список methodsToSpyOn заменял методы, найденные на классе. В 2.0 список добавляется к ним. Так всегда работал jest-auto-spies.
Если спаями должны стать только перечисленные методы, используйте onlyMethodsToSpyOn:
- createSpyFromClass(ApiService, { methodsToSpyOn: ['get', 'post'] }); // 1.x: только эти два
+ createSpyFromClass(ApiService, { onlyMethodsToSpyOn: ['get', 'post'] }); // 2.x: только эти дваЧто делать:
- Вы пришли с
jest-auto-spiesи об этой опции не задумывались — ничего. Спеки ведут себя так же, как под Jest. - Вы рассчитывали на ограничение — переименуйте ключ.
- Краткая запись массивом
createSpyFromClass(Service, ['a', 'b'])теперь тоже добавляет. Чтобы ограничить, пишите{ onlyMethodsToSpyOn: ['a', 'b'] }.
Если какое-то место останется без переименования, спай получит больше методов, чем раньше, а не меньше. Спека станет шумнее, но не сломается.
instanceMethodsToSpyOn не изменился и теперь работает так же, как methodsToSpyOn. Разница только в том, что имя говорит читателю. В новом коде берите instanceMethodsToSpyOn.
2. Ленивые спаи методов — поведение по умолчанию
Метод становится спаем при первом обращении, а не в момент создания объекта-спая.
Как раньше работают:
Object.keys, спред и снапшоты — они видят те же ключи: заготовки методов перечисляемые геттеры.vi.isMockFunction,calledWith,resetAutoSpyиclearAutoSpy.
Меняется одно: до первого обращения дескриптор свойства метода — геттер, а не значение.
Что делать: ничего, если спека не проверяет Object.getOwnPropertyDescriptor(...).value до обращения к методу. Такому спаю передайте { lazySpies: false }.
Тест, который вызывает все методы, платит за геттер около 5 % времени и 1 % памяти. Тест, который трогает пару методов, экономит гораздо больше, поэтому ленивый режим включён по умолчанию.
provideAutoSpy больше не включает флаг сам: ядро делает это для всех фабрик.
До 2.0 ленивые спаи были только у provideAutoSpy, поэтому путь через Angular без видимой причины работал быстрее обычного.
3. Предупреждение о неизвестном методе переехало в onlyMethodsToSpyOn
В дополняющем списке имя метода, которого нет на классе, — допустимая запись. Так делают спай на функцию, которую конструктор кладёт в поле экземпляра. Поэтому старое предупреждение срабатывало на правильном коде.
В ограничивающем списке опечатка оставляет настоящий метод без спая. Поэтому предупреждение теперь проверяет onlyMethodsToSpyOn.
И дальше
Переход на 3.0 — одна строка в package.json. Переход на 4.0 убирает rxjs из вашей TypeScript-программы.