React Navigation:如何测试使用 withNavigation HOC 的组件?
React Navigation: How to test components that use the withNavigation HOC?
我正在使用 Jest 为我的 React Native 应用编写单元测试。我有一个组件,包裹在 withNavigation
HOC.
我的问题是我的测试崩溃了,抛出:
● 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.
我正在使用 @testing-library/react-native
for my tests and I 这样的:
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 };
这适用于 Redux 上下文,但不适用于导航提供程序。
如何测试包装在 withNavigation
HOC 中的组件?
更新:
我尝试了这样的建议答案:
jest.mock('react-navigation', () => ({
withNavigation: Component => props => <Component {...props} />,
}));
afterAll(() => {
jest.restoreAllMocks();
});
但这不起作用。我收到错误:
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.
你应该模拟 react-navigation,像这样:
jest.mock("react-navigation", ({ withNavigation: (component) => component })
然后将道具传递给您的组件:
const mockProps = {
navigation: { navigate: jest.fn() }
}
wrapper = shallow(<LoginScreen {...mockProps}/>)
根据忽必烈的回答,我是这样解决的:
jest.mock('react-navigation', () => ({
withNavigation: Component => props => (
<Component navigation={{ navigate: jest.fn() }} {...props} />
),
SafeAreaView: ({ children }) => <>{children}</>,
}));
afterAll(() => {
jest.restoreAllMocks();
});
我不得不嘲笑 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 };
我正在使用 Jest 为我的 React Native 应用编写单元测试。我有一个组件,包裹在 withNavigation
HOC.
我的问题是我的测试崩溃了,抛出:
● 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.
我正在使用 @testing-library/react-native
for my tests and I
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 };
这适用于 Redux 上下文,但不适用于导航提供程序。
如何测试包装在 withNavigation
HOC 中的组件?
更新:
我尝试了这样的建议答案:
jest.mock('react-navigation', () => ({
withNavigation: Component => props => <Component {...props} />,
}));
afterAll(() => {
jest.restoreAllMocks();
});
但这不起作用。我收到错误:
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.
你应该模拟 react-navigation,像这样:
jest.mock("react-navigation", ({ withNavigation: (component) => component })
然后将道具传递给您的组件:
const mockProps = {
navigation: { navigate: jest.fn() }
}
wrapper = shallow(<LoginScreen {...mockProps}/>)
根据忽必烈的回答,我是这样解决的:
jest.mock('react-navigation', () => ({
withNavigation: Component => props => (
<Component navigation={{ navigate: jest.fn() }} {...props} />
),
SafeAreaView: ({ children }) => <>{children}</>,
}));
afterAll(() => {
jest.restoreAllMocks();
});
我不得不嘲笑 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 };