Jest.js 使用react-test-renderer测试异步组件DidMount()

643ylb08  于 2022-12-08  发布在  Jest
关注(0)|答案(3)|浏览(192)

我有一个组件,它在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秒,可能它也会工作得更少,因为异步调用无论如何都是模拟的,但我永远不能真正知道)
我的问题是,是否有人有更好的办法来解决这个问题?

kkbh8khc

kkbh8khc1#

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

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

js5cn81o2#

您可以使用waitforexpect包: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)的函数现在是异步函数。

pb3s4cty

pb3s4cty3#

参加聚会有点晚了,但也面临着问题。下面是我使用act的一个方便快捷的函数:

import renderer from "react-test-renderer"
import { ReactElement } from "react"
import { act } from "@testing-library/react-native"

export const expectToMatchSnapshot = async (component: ReactElement) => {
   let tree

   await act(async () => {
      tree = renderer.create(component)
   })

   expect(tree.toJSON()).toMatchSnapshot()
}

在您的情况下,您应仅在此时添加:

test("should render ***", async () => {
   await expectToMatchSnapshot(<IndexScreen/>)
}

相关问题