Похоже, проблема в том, что текущие библиотеки тестирования не обрабатывают useEffect
должным образом (на данный момент), поэтому тест всегда будет неудачным. Вы можете найти отслеживаемую в настоящее время проблему здесь .
В примечании к вашему примеру хука необходимо использовать useEffect
, чтобы работать.
import React, { useState, useEffect } from "react";
const Example = () => <div className="child">child</div>;
const App = () => {
const [showChild, setShowChild] = useState(true);
useEffect(() => {
const timer = setTimeout(() => setShowChild(false), 5000);
return () => {
clearTimeout(timer);
};
}, []);
return <div className="App">{showChild && <Example />}</div>;
};
export default App;
Рабочий пример :
Тем не менее, обходной путь - использовать классы на данный момент.
Вот локальный пример, демонстрирующий проблему с ловушкой, и пример рабочего класса : https://github.com/mattcarlotta/hooks-versus-classes
Для установки:
- открыть терминал на рабочий стол.
- введите
git clone git@github.com:mattcarlotta/hooks-versus-classes.git
и введите.
- тип
cd hooks-versus-classes
.
- тип
yarn install
или npm install
.
- введите
yarn test
или npm run test
для запуска тестов (они все пройдут, но one сгенерирует console.error
и будет утверждено, что не работает должным образом) .
- введите
yarn dev
или npm run dev
для запуска проекта.
Пример кода рабочего класса:
App.js
import React, { Component } from 'react';
const Example = () => <div className="child">child</div>;
class App extends Component {
state = { showChild: true };
componentDidMount = () => this.setTimer(); // setup timeout on mount
componentWillUnmount = () => this.clearTimer(); // remove timeout in case of component unmount
clearTimer = () => clearTimeout(this.timeout); // clear timeout
timer = () => this.setState({ showChild: false }, () => this.clearTimer()); // update state and clear timeout
setTimer = () => (this.timeout = setTimeout(this.timer, 5000)); // setup a 5s timeout
render = () => <div>{this.state.showChild && <Example />}</div>;
}
export default App;
App.test.js
import App from './App';
describe('App', () => {
it('initially renders a child component', () => {
expect(wrapper.find('.child')).toHaveLength(1);
});
it('removes child component after a 5 second timeout', () => {
jest.advanceTimersByTime(5000);
expect(wrapper.find('.child')).toHaveLength(0);
});
});