J. *_*ers 6 jestjs react-native higher-order-components react-navigation react-testing-library
我正在使用 Jest 为我的 React Native 应用程序编写单元测试。我有一个组件,它被包裹在withNavigationHOC 中。
我的问题是我的测试崩溃,抛出:
? LoginScreen component › given no props: should render a login form
Invariant Violation: withNavigation can only be used on a view hierarchy of a navigator. The wrapped component is unable to get access to navigation from props or context.
Run Code Online (Sandbox Code Playgroud)
我正在使用@testing-library/react-native我的测试,我设置了一个自定义渲染方法,如下所示:
import { render } from '@testing-library/react-native';
import React from 'react';
import { NavigationContext } from 'react-navigation';
import { Provider } from 'react-redux';
import store from '../src/store';
const WithProviders = ({ children }) => {
return (
<Provider store={store}>
<NavigationContext.Provider>{children}</NavigationContext.Provider>
</Provider>
);
};
const customRender = (ui, options) =>
render(ui, {
wrapper: WithProviders,
...options,
});
export * from '@testing-library/react-native';
export { customRender as render };
Run Code Online (Sandbox Code Playgroud)
这适用于 Redux 上下文,但不适用于导航提供程序。
如何测试封装在withNavigationHOC 中的组件?
更新:
我尝试了这样的建议答案:
jest.mock('react-navigation', () => ({
withNavigation: Component => props => <Component {...props} />,
}));
afterAll(() => {
jest.restoreAllMocks();
});
Run Code Online (Sandbox Code Playgroud)
但这不起作用。我收到错误:
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Run Code Online (Sandbox Code Playgroud)
根据 Kubilay 的回答,我是这样解决的:
jest.mock('react-navigation', () => ({
withNavigation: Component => props => (
<Component navigation={{ navigate: jest.fn() }} {...props} />
),
SafeAreaView: ({ children }) => <>{children}</>,
}));
afterAll(() => {
jest.restoreAllMocks();
});
Run Code Online (Sandbox Code Playgroud)
我不得不嘲笑withNavigation和SafeAreaView。
这仍然是一种非常不满意的方式。如果有人知道如何在自定义渲染方法中注入正确的 React Navigation 提供程序,我将非常感激。
理想情况下,应该有一种方法来配置将内容包装在容器中的自定义渲染器。这是我如何使用 Redux 做到这一点。
import { render } from '@testing-library/react-native';
import React from 'react';
import { Provider } from 'react-redux';
import configureStore from '../src/redux/store.js';
const store = configureStore();
const WithProviders = ({ children }) => (
<Provider store={store}>{children}</Provider>
);
const customRender = (ui, options) =>
render(ui, { wrapper: WithProviders, ...options });
export * from '@testing-library/react-native';
export { customRender as render };
Run Code Online (Sandbox Code Playgroud)