#reactjs #jestjs #react-hooks #mocking #enzyme
Вопрос:
У меня есть компонент, который выглядит так:
import React, { useRef } from 'react'
import Modal from '@example-component-library/modal'
import ModalHeader from '@example-component-library/modal/header'
import ModalFooter from '@example-component-library/modal/footer'
const ExampleModal = () => {
const headerRef = useRef(null)
...
return (
<Modal
headerRef={headerRef}
isOpen={showModal}
header={
<ModalHeader closeModal={handleCloseModal} headerRef={headerRef} content="Modal Header"/>
}
footer={<ModalFooter closeModal={handleCloseModal} />}
>
Modal body stuff
</Modal>
)
}
Тогда у меня будет тест:
it('renders as expected', () => {
const wrapper = mount(
<TestWrapper>
<ExampleModal />
</TestWrapper>
)
expect(wrapper.exists()).toBe(true)
})
})
и тут у меня возникает ошибка
TypeError: Cannot read property 'style' of null
28 |
29 | it('renders as expected', () => {
> 30 | const wrapper = mount(
| ^
31 | <TestWrapper>
32 | <ExampleModal />
33 | </TestWrapper>
Если я изменю ExampleModal
реквизит header
на:
<Modal header={<>HEADER</>} ...>
Тест работает без проблем — поэтому я считаю, что это как — то связано с headerRef
тем, что я пробовал jest.spyOn
, и несколькими другими решениями, — однако я всегда получаю одну и ту же ошибку.
Разметка модального Компонента
const ModalHeader = ({ headerRef, content, ...}) => (
<div>
<h5 tabIndex={-1} ref={headerRef}> {content}</h5>
...
</div>
)
const Modal = ({ id, isOpen, header, headerRef, children, ...}) => {
useEffect(() => {
const selectorId = `#${id}`
const selectedElement: HTMLElement = document.querySelector(selectorId)
// set focus to the header when modal is opened
if (isOpen amp;amp; headerRef.current) {
headerRef.current.focus()
// React Ref wasn't working for this case
selectedElement.style.right = '0px'
document.body.style.overflow = 'hidden'
setPostAnimationState(true)
}
if (!isOpen amp;amp; document.querySelector(selectorId)) {
// React Ref wasn't working for this case
document.body.style.overflow = 'auto'
selectedElement.style.right = '-768px'
setTimeout(() => {
setPostAnimationState(false)
}, 400)
}
}, [isOpen, headerRef, id])
return (
<div>
...
{!!header amp;amp; header}
<div className="modal-content" ref={!header ? headerRef : null}>
{children}
</div>
...
</div>
)
}
Комментарии:
1. Почему вы переходите
headerRef
к обоимModal
иModalHeader
? Где ты шпионишь за чем-нибудь в тестах? Можете ли вы обновить свой вопрос, включив в него весь соответствующий код? (ModalHeader
,ModalFooter
, тестовый код и т. Д.)2. @DrewReese — обновил свой пост с помощью разметки компонентов. Я не создавал компонент, не видел, как он работает и где его не хватает — я просто не уверен, как это сделать или как протестировать его без использования .
style
shallow
Я бы хотел использоватьmount
Ответ №1:
На самом деле это не имело никакого отношения ref
, это было связано с тем document.body
. Итак, вот мой тест, который работает сейчас:
it('renders as expected', () => {
const wrapper = mount(
<TestWrapper>
<ExampleModal />
</TestWrapper>,
{ attachTo: document.body }
)
expect(wrapper.exists()).toBe(true)
})
})