#reactjs #unit-testing #jestjs #enzyme
#reactjs #модульное тестирование #jestjs #enzyme
Вопрос:
Я хочу проверить, вызывается ли a внутри компонента при нажатии кнопки, но я проваливаю тест и получаю 0 вызовов при нажатии.
test('when clicked popUphandler function is called', () => {
let popUpHandler = jest.fn();
const wrapper = mount(<StaticRouter><Header popUpHandler={popUpHandler}/></StaticRouter>)
wrapper.find('.header__navClosed').simulate('click');
expect(popUpHandler).toBeCalled();
})
function Header() {
const [isPopUp, setPopUp] = useState(false);
const popUpHandler = () => {
setPopUp(!isPopUp);
};
return (
<div className='header'>
{isPopUp === false ?
<button className='header__navClosed' onClick={popUpHandler}>
</button>
:
<Nav data-testid='navigation' popUpHandler={popUpHandler}/>
}
</div>
);
};
Комментарии:
1.
Header
не использует никаких реквизитов, поэтому передачаpopUpHandler={jest.fn()}
ему реквизита в тесте ничего не значит. Вы можете настроить таргетинг на кнопку, имитировать щелчок, дождаться обновления состояния и утверждать, чтоwrapper.find('.header__navClosed')
теперь оно равно нулю или длине 0, или что теперь вы можете найти тестовый идентификатор «навигации».2. я уже создал тест для этого, используя toHaveLength(#) , но я подумал, что мне также следует проверить, вызывается ли функция popUpHandler, просто чтобы показать, хотя я знаю, что переключение между кнопкой и навигацией работает. Но для будущих целей, если бы я хотел проверить, вызывалась ли функция внутри компонента, как бы я это сделал?
3. Вы должны протестировать свои компоненты пользовательского интерфейса, в любом случае взаимодействуя с его API, то есть с реквизитом и пользовательским интерфейсом. Если вы хотите проверить, что кнопка переключает что-то в пользовательском интерфейсе, тогда проверьте это . IMO enzyme заставляет вас слишком запутываться во внутренних компонентах ваших компонентов, что трудно считать тесты действительными, поскольку то, как остальная часть вашего приложения и пользователи взаимодействуют с ним, совершенно разные. Компоненты и пользователи не обращаются к другим компонентам и не настраивают внутреннее состояние и детали реализации.
4. о, хорошо, я понимаю, что вы говорите. Спасибо
5. Я знаю, что это немного не по теме, но я настоятельно рекомендую вам проверить react-testing-library для тестирования компонентов пользовательского интерфейса. Я предупреждаю, однако, что, исходя из enzyme, это будет казаться очень странным, но как только вы лучше поймете, как думать о тестировании вашего пользовательского интерфейса, это имеет гораздо больше смысла и, на мой взгляд, позволяет вам писать более четкие и эффективные тесты.
Ответ №1:
Похоже, проблема в том, чтобы забыть о вызове popUpHandler
обратного вызова. Просто вызовите эту опору, тогда она будет работать так, как ожидалось:
function Header(props) {
const [isPopUp, setPopUp] = useState(false);
const popUpHandler = () => {
setPopUp(!isPopUp);
// Invoke the callback from `props` argument
props.popUpHandler();
};
return (
<div className='header'>
{isPopUp === false ?
<button className='header__navClosed' onClick={popUpHandler}>
</button>
:
<Nav data-testid='navigation' popUpHandler={popUpHandler}/>
}
</div>
);
};
В случае сохранения компонента как неконтролируемого способа, вы можете переключить свой тест на проверку доступности DOM следующим образом:
// Check your button was closed
expect(wrapper.find('.header__navClosed').length).toBe(0);
Комментарии:
1. я немного смущен, мой компонент работает, и я не пытаюсь передать что-либо в заголовок. Я просто хочу имитировать щелчок и проверить, вызвана ли функция popUpHandler. но он показывает 0 для полученных вызовов.
2. Проблема в том, что вы написали компонент с неконтролируемым стилем, но вы тестировали как контролируемый тип, из-за чего ваш тест не работает. Если вы все еще предпочитаете неконтролируемый, вам, возможно, придется либо переключиться на проверку доступности DOM (проверка доступности DOM после нажатия), либо сделать ваш компонент контролируемым
3. Я дал вам еще один совет для тестирования вашего неконтролируемого компонента
4. Я уже провел успешный тест на это, спасибо. Но мне сказали, что это работает. я также должен написать тест, чтобы показать, что функция popUpHandler также вызывается.
5. @Bpun1p Если ваш тест «нажимает» на кнопку, и обработчик обновляет состояние, и вы можете утверждать, что пользовательский интерфейс обновлен, тогда я говорю, что этого достаточно. Эта функция и строки кода будут отображаться в отчете о покрытии кода.