在Promise中对React组件的setState更新进行Jest测试

时间:2019-05-02 19:19:41

标签: reactjs jestjs enzyme

给出一个名为ListContainer的React组件,该组件具有如下功能来加载数据:

loadList() {
    this.setState({loading: true});

    return this.props.api.get({
        sort: this.props.sort.order,
        search: this.props.search.query,
        limit: this.props.pager.limit,
        offset: this.props.pager.offset
    }).then((response: ApiResponse) => {
        this.setState({
            listItems: response.data.records,
            itemCount: response.data.meta.count,
            error: undefined
        })
    }).catch((error: ApiError) => {
        this.setState({
            error: error
        })
    }).then(() => {
        this.setState({
            loading: false
        })
    })
}

我正在尝试编写一个测试,以确保将响应数据写入组件的状态。

test('loads list items', () => {
        const testApi = {
            get: jest.fn(() => Promise.resolve())
        };

        // Omitting some additional props for brevity.
        wrapper = shallow(<ListContainer api={testApi}/>);

        const testItems = [
            'Test Item 1',
            'Test Item 2',
        ];

        testApi.get.mockImplementationOnce(() =>
            Promise.resolve({
                data: {records: testItems}
            })
        );

        return wrapper.instance().loadList()
            .then(() => {
                expect(wrapper.update().state().listItems).toBe(testItems)
            });
    })

我可以看到我的模拟正在正确返回测试数据(通过console.log(response)函数中的loadList),但是测试仍然失败。在断言我的期望之前,如何确保setState已完成?

1 个答案:

答案 0 :(得分:1)

您已经关闭!

您只需要将.data.meta.count添加到您的响应模拟中,由于当前模拟中未包含该代码,现在代码最终会引发错误。

只需将您的模拟更改为此:

testApi.get.mockImplementationOnce(() =>
  Promise.resolve({
    data: {
      records: testItems,
      meta: { count: 2 }  // <= include .data.meta.count
    }
  })
);

...那应该解决它!