测试包含AppLoading组件的应用

时间:2020-07-04 19:43:06

标签: react-native jestjs expo react-native-testing-library

我是单元测试领域的新手,我才刚刚开始为我的React Native(Expo)应用编写测试。经过研究,我终于开始使用Jest和React Native Testing Library(https://github.com/callstack/react-native-testing-library)。

请考虑以下使用AppLoading组件(https://docs.expo.io/versions/latest/sdk/app-loading/)的情况。

const App: React.FC = () => {
    const [resourcesHasLoaded, setResourcesHasLoaded] = useState<boolean>(false);

    const cacheResources = useCallback(async (): Promise<any> => {
        const images = [require('./assets/icon.png')];

        const cacheImages = images.map((image) => {
            return Asset.fromModule(image).downloadAsync();
        });

        return Promise.all([cacheImages]);
    }, []);

    if (resourcesHasLoaded) {
        return <Text>Hello world</Text>;
    }

    return (
        <AppLoading
            startAsync={cacheResources}
            onError={console.warn}
            onFinish={() => setResourcesHasLoaded(true)}
        />
    );
};

运行测试时,看起来像这样:

describe('App.tsx', () => {
    it('should be able to render', async () => {
        render(<App />);
    });
});

我最终遇到以下错误(尽管通过测试):

Warning: An update to App inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

因此,我通过以下方式用renderact包裹起来:

act(() => {
    render(<App />);
});

...导致了同样的错误。

但是,如果我通过以下方式将onFinish回调包装在组件中,则测试将通过而不会发出警告。

onFinish={() => act(() => setResourcesHasLoaded(true))}

但是我真的想用测试专用功能污染我的React组件吗?我没有看到这样的例子,所以我只能认为这是一种不好的做法。

这里有什么建议吗?

更新 我得到@Estus Flask在我的waitFor之后的建议中使用render。这样就可以了...测试现在通过了。

https://callstack.github.io/react-native-testing-library/docs/api/#waitfor

describe('App.tsx', () => {
    it('should be able to render', async () => {
        const { findByText } = render(<MyApp />);
        await waitFor(() => findByText('Hello world'));
    });
});

0 个答案:

没有答案