У меня есть компонент, который отправляет запрос fetch
при монтировании и отображает результаты.
Я пытаюсь создать тестовый снимок этого компонента после запрос завершен. Я уже давно бьюсь об этом, вот вопрос по SO, который не дал мне удачи:
- Асинхронный снимок компонента с использованием Jest и Redux
- Как проверить асинхронные компоненты с помощью Jest?
- React + Jest - тестирование асинхронных компонентов и ожидание монтирования
- Как сделать снимок шутки после извлечения данных по axios в componentDidMount?
Это мой fetch
макет:
// Mocking the global.fetch included in React Native
global.fetch = jest.fn()
// Helper to mock a success response (only once)
fetch.mockResponseSuccess = (body, status = 200) => {
fetch.mockImplementationOnce(() =>
Promise.resolve({
status,
json: () => Promise.resolve(JSON.parse(body))
})
)
}
// Helper to mock a failure response (only once)
fetch.mockResponseFailure = error => {
fetch.mockImplementationOnce(() => Promise.reject(error))
}
Компонент (упрощенно):
export class Posts extends Component {
constructor(props) {
super(props)
this.state = {
items: [],
loading: false
}
this._getItems()
}
async _getItems() {
const resp = await fetch(
"/user/recent_posts",
{
method: "GET"
}
)
this.setState({
items: resp.json["data"],
})
}
render() {
// renders this.state.items
}
Это тест:
test("view renders correctly", async done => {
fetch.mockResponseSuccess(
JSON.stringify({
data: [
{ caption: "test", likes: 100 },
{ caption: "test2", likes: 200 }
]
})
)
// also tried with setTimeout and setImidiate
const wrapper = await shallow(<Posts />) // also tried with react-test-renderer
await wrapper.update() // didn't work with or without
// await waitForState(wrapper, state => state.loading === false) --> didn't work
// process.nextTick(() => {.... --> didn't work
// jest.runTimersToTime(1) --> didn't work
expect(wrapper).toMatchSnapshot()
done()
})
Проблема в том, что this.state.items
в снимке всегда пуст.