Реагировать на нативное асинхронное тестирование Jest-компонентов - PullRequest
0 голосов
/ 17 июня 2019

У меня есть компонент, который отправляет запрос fetch при монтировании и отображает результаты.

Я пытаюсь создать тестовый снимок этого компонента после запрос завершен. Я уже давно бьюсь об этом, вот вопрос по SO, который не дал мне удачи:

  1. Асинхронный снимок компонента с использованием Jest и Redux
  2. Как проверить асинхронные компоненты с помощью Jest?
  3. React + Jest - тестирование асинхронных компонентов и ожидание монтирования
  4. Как сделать снимок шутки после извлечения данных по 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 в снимке всегда пуст.

1 Ответ

0 голосов
/ 18 июня 2019

Для дальнейшего использования вот что решило это для меня:

test("view renders correctly", done => {
    // mock response here...
    const wrapper = shallow(<Posts />)
    setImmediate(() => {
        wrapper.update()
        try {
            expect(wrapper).toMatchSnapshot()
        } catch (e) {
            console.log(e)
        }

        done()
    })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...