使用react-test-renderer测试异步componentDidMount()

时间:2019-10-15 16:46:36

标签: javascript reactjs react-native jestjs

我有一个在其componentDidMount()函数中执行一些SQLite加载的组件

async componentDidMount() {
    try {
        const user = await this.userDao.getUserData();
        const setupNeeded = user === null;
        if( setupNeeded ) {
            this.setState({
                status : 'setup'
            });
        }
        else {
            this.setState({
                status : 'ready',
                seed: user.seed
            })
        }
    } catch (e) {
        logger.error("Error during db query", e);
        this.setState({
            status: 'corrupted'
        });
    }
}

我想在解决对getUserData()的调用并相应地设置状态之后,测试渲染结果。 现在在测试中,我已经模拟了对数据库的实际调用,因此应立即解决Promise,但是这样的测试无法按预期进行:

最初,我是这样尝试的:

test('Should render SetNewPasswordScreen', async () => {
    const tree = await renderer.create(<IndexScreen/>);
    const json = tree.toJSON();
    // expect stuff
});

但是在这种情况下,json包含初始render()调用的数据。

这样做会起作用:

 test('Should render SetNewPasswordScreen', (done) => {
     const tree = renderer.create(<IndexScreen/>);
     setTimeout(() => {
         const json = tree.toJSON();
         // expect stuff
     }, 5000);
 });

但这不是理想的,因为我只是猜测5秒后一切都会完成,但是我不知道。另外,如果测试需要5秒钟才能完成,那么它就不那么合适了。 (我随意使用了5秒,由于异步调用还是被模拟了,所以它可能也可以用更少的时间,但是我永远无法真正知道)

我的问题是,是否有人对如何解决此问题有更好的主意?

2 个答案:

答案 0 :(得分:0)

您可以使用“等待期待”包: https://www.npmjs.com/package/wait-for-expect

test('Should render SetNewPasswordScreen', async (done) => {
     const tree = renderer.create(<IndexScreen/>);

     await waitForExpect(() => {
       const json = tree.toJSON();
       // expect stuff
     });
 });

请注意,传递到test('...', fn)的函数现在是异步函数。

答案 1 :(得分:0)

it('should render setNewPassWordScreen', async () => {
   const tree = await renderer.create(<IndexScreen/>);
   const instance = tree.getInstance();

   await instance.componentDidMount();
   // expect other stuff.
});