169 похожих чатов

Кто как организовывает тесты? Есть компонент A, который, среди прочих, используется

в компоненте B, который так же используется в компоненте C.
Компонент А покрыт модульными тестами.

Получается так, что при тестировании компонента B на полную работоспособность, приходится либо повторять некоторые тесты из тестов компонента А, либо мокать А и проверять только переданные в него пропсы. Такая же ситуация возникает с компонентом C, который должен повторять тесты для компонента А и B, либо мокать B.

Оба подхода кажутся неправильными, т.к. при применении первого, прохождение теста зависит от правильности работы других компонентов, а при применении второго приходится учитывать внутреннюю реализацию, и такие тесты перестают быть актуальными при малейшем рефакторинге

19 ответов

3 просмотра

Ну по мне тут есть несколько вариантов. 1) Ты протестировал компонент A, далее ты тестируешь компонент B, подменяя компонент A на какую нибудь заглушку. (Для этого в enzyme например есть shallow render) И тогда получается если упал тест в B, ты знаешь что виноват именно компонент B, а не какой то другой. 2) Второй подход не мокать компоненты и тестировать как есть (по сути интеграционные тесты получаются). Kent Dodds говорил в одной статье про shallow render: "Какая разница что твой юнит тест с замоканным компонентом проходит если модуль в целом не работает". И получается ты тестируешь сразу работоспособность целого модуля ничего не мокая, делая по большей части интеграционные тесты. В твоем случае при применении первого подхода когда ты проверяешь полную работоспособность, логично что твой тест упадет если модуль который он использует сломанный (Интеграционный тест получается), значит твоя система не работает в целом. Во втором случае ты мокаешь компонент и у тебя получается чистый юнит тест без каких то зависимостей. Ты проверил работоспособность конкретно модуля B. И если он у тебя ломается при небольшом рефакторинге когда общее поведение сохраняется, то это немного странно.

Sergey-Grishchenko Автор вопроса

Изменение АПИ компонента А может сломать тесты компонента B, если тесты проверяют работоспособность B при моке А, который имитирует его правильную работу. Например, у А есть коллбэк. У B есть коллбэк, который с какими-то изменениями пробрасывается в А. Есть тест, который проверяет правильно ли вызывается коллбэк, переданный в B, когда А вызывает коллбэк. Получается, изменив имя коллбэка в А, упадёт данный тест для B. Это логично с одной стороны, т.к. это спасает от ситуации, когда интерфейс поменяли, а в каком-то компоненте использование поменять забыли. Но получается очень шаткая "конструкция". По поводу интеграционных тестов согласен. Реализуем их для каждой фичи, но shared компоненты такими тестами не протестировать. И при падении интеграционного теста потом не так уж и легко найти причину его падения

Sergey-Grishchenko Автор вопроса

По поводу Enzyme думал тоже, но у него с shallow render'ом и эффектами есть проблема

Если мы пишем unit тест компонента B, то он не должен проверять как там что то вызывается в A. Он предполагает что компонент A изначально рабочий, для этого мы его и мокаем.

Это уже интеграционный тест. Ты проверяешь работу двух модулей. И логично если сломается один, то другой тоже упадет

Sergey-Grishchenko Автор вопроса

it( 'should call onAClick with current input value on A click', () => { let onClick; mockedA.mockImplementation(props => (onClick = props.onClick)) const onAClick = jest.fn() const defaultValue = {a: 1} render(<B onAClick={onAClick} defaultValue={defaultValue} />) onClick() expect(onAClick).toBeCalledWith(defaultValue) } )

Если честно, немного сложно понять что тут происходит

Sergey-Grishchenko Автор вопроса

Компонент А замокан, мы получаем переданный в его пропсы коллбэк и вызываем его сами, чтобы проверить правильно ли отработает логика в компоненте B, которая должна произойти по этому коллбэку. В данном случае, B должен вызвать коллбэк onAClick с текущим значением внутреннего инпута. Но так же это мог бы быть какой-нибудь сайд эффект

Ну это вроде unit тест. У тебя компонент A тут указан замоканный. И если ты изменишь реальный компонент A, то этот тест не должен упасть. Но сама система уже может не работать.

Sergey-Grishchenko Автор вопроса

Вообще да. Если изменится АПИ А, то придётся поменять компонент B для работоспособности. И, следовательно, поменять юнит тест для этого, поменяв название пропа, который мы забираем из А

Если изменится A, то упадет тест только для компонента A. Тест для компонента B останется рабочим

И ещё есть вопрос если можно конечно почему когда я querySelectorAll("button") делаю и хочу что бы при клике изменились все кнопки оно ошибку дают но только при querySelector(button) работает но только первую попавшийся задет тот свет

Sergey-Grishchenko Автор вопроса

Да, но B будет нерабочим. Чтобы починить B, придётся поменять название коллбэка, который передаётся в A ...<A onClick={handleAClick} -> <A newOnClick={handleAClick} , а это уже в свою очередь приведёт к падению теста

querySelectorAll возвращает тебе массив

Да nodeList а как можно с этим работать что бы получилось использовать map и усвоить знание ?

Коллекцию

Да, пардон

Тебе нужно получить массив из коллекции и его ты можешь мапить

Для каждого из них так положено делать x[0].style.backgroundColor = "red";

Похожие вопросы

Обсуждают сегодня

Интересно, нет ли какого-то способа получить из dll не адрес самой метки, а адрес со смещением?
The Bird of Hermes
54
Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
58
Друзья, за кем?
Magic
12
А шо, ты этой библиотекой пользуешься?
Darkanronpa Dark Hole
10
Сообщение* в закодированном виде. То есть, просто сделать sendMessage?text=Привет бла-бла! не получится, надо в HEX переводить, и добавлять процент, типа такого: sendMessage?t...
КТ315
21
А случайно нет ли в паскале штатной возможности передать указатель и количество туда где array of в качестве аргумента?
zamtmn
25
Всем привет. Кто-то может подсказать, как можно перевести значения Selection поля, если список значений в нем формируется динамически? Я изначально их получаю из selection дру...
Наталья Селезнева
6
Или даже по-другому вопрос выстрою Есть ли вообще в electron'e для винды, возможность кнопки действий в нотификацию впихнуть ?
Андрей
7
приветы , подскажите что я не так сделал , почему у меня скрипт не работает в программе Revit ? ;Autohotkey_RU IfWinActive ("ahk_exe Revit.exe") ; только в открытом Revit Gu...
Anton Terentev
2
> комьюнити я бы не судил по этому чату. Как мы видели по статам просмотров нескольких телеговских постов, то в чате их набивается 30-40 или даже выше, когда как общаются акти...
Constantin F.
4
Карта сайта