в компоненте B, который так же используется в компоненте C.
Компонент А покрыт модульными тестами.
Получается так, что при тестировании компонента B на полную работоспособность, приходится либо повторять некоторые тесты из тестов компонента А, либо мокать А и проверять только переданные в него пропсы. Такая же ситуация возникает с компонентом C, который должен повторять тесты для компонента А и B, либо мокать B.
Оба подхода кажутся неправильными, т.к. при применении первого, прохождение теста зависит от правильности работы других компонентов, а при применении второго приходится учитывать внутреннюю реализацию, и такие тесты перестают быть актуальными при малейшем рефакторинге
Ну по мне тут есть несколько вариантов. 1) Ты протестировал компонент A, далее ты тестируешь компонент B, подменяя компонент A на какую нибудь заглушку. (Для этого в enzyme например есть shallow render) И тогда получается если упал тест в B, ты знаешь что виноват именно компонент B, а не какой то другой. 2) Второй подход не мокать компоненты и тестировать как есть (по сути интеграционные тесты получаются). Kent Dodds говорил в одной статье про shallow render: "Какая разница что твой юнит тест с замоканным компонентом проходит если модуль в целом не работает". И получается ты тестируешь сразу работоспособность целого модуля ничего не мокая, делая по большей части интеграционные тесты. В твоем случае при применении первого подхода когда ты проверяешь полную работоспособность, логично что твой тест упадет если модуль который он использует сломанный (Интеграционный тест получается), значит твоя система не работает в целом. Во втором случае ты мокаешь компонент и у тебя получается чистый юнит тест без каких то зависимостей. Ты проверил работоспособность конкретно модуля B. И если он у тебя ломается при небольшом рефакторинге когда общее поведение сохраняется, то это немного странно.
Изменение АПИ компонента А может сломать тесты компонента B, если тесты проверяют работоспособность B при моке А, который имитирует его правильную работу. Например, у А есть коллбэк. У B есть коллбэк, который с какими-то изменениями пробрасывается в А. Есть тест, который проверяет правильно ли вызывается коллбэк, переданный в B, когда А вызывает коллбэк. Получается, изменив имя коллбэка в А, упадёт данный тест для B. Это логично с одной стороны, т.к. это спасает от ситуации, когда интерфейс поменяли, а в каком-то компоненте использование поменять забыли. Но получается очень шаткая "конструкция". По поводу интеграционных тестов согласен. Реализуем их для каждой фичи, но shared компоненты такими тестами не протестировать. И при падении интеграционного теста потом не так уж и легко найти причину его падения
По поводу Enzyme думал тоже, но у него с shallow render'ом и эффектами есть проблема
Если мы пишем unit тест компонента B, то он не должен проверять как там что то вызывается в A. Он предполагает что компонент A изначально рабочий, для этого мы его и мокаем.
Это уже интеграционный тест. Ты проверяешь работу двух модулей. И логично если сломается один, то другой тоже упадет
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) } )
Если честно, немного сложно понять что тут происходит
Компонент А замокан, мы получаем переданный в его пропсы коллбэк и вызываем его сами, чтобы проверить правильно ли отработает логика в компоненте B, которая должна произойти по этому коллбэку. В данном случае, B должен вызвать коллбэк onAClick с текущим значением внутреннего инпута. Но так же это мог бы быть какой-нибудь сайд эффект
Ну это вроде unit тест. У тебя компонент A тут указан замоканный. И если ты изменишь реальный компонент A, то этот тест не должен упасть. Но сама система уже может не работать.
Вообще да. Если изменится АПИ А, то придётся поменять компонент B для работоспособности. И, следовательно, поменять юнит тест для этого, поменяв название пропа, который мы забираем из А
Если изменится A, то упадет тест только для компонента A. Тест для компонента B останется рабочим
И ещё есть вопрос если можно конечно почему когда я querySelectorAll("button") делаю и хочу что бы при клике изменились все кнопки оно ошибку дают но только при querySelector(button) работает но только первую попавшийся задет тот свет
Да, но B будет нерабочим. Чтобы починить B, придётся поменять название коллбэка, который передаётся в A ...<A onClick={handleAClick} -> <A newOnClick={handleAClick} , а это уже в свою очередь приведёт к падению теста
querySelectorAll возвращает тебе массив
Да nodeList а как можно с этим работать что бы получилось использовать map и усвоить знание ?
Коллекцию
Да, пардон
Тебе нужно получить массив из коллекции и его ты можешь мапить
Для каждого из них так положено делать x[0].style.backgroundColor = "red";
Обсуждают сегодня