react-native - react 导航 : How to test components that use the withNavigation HOC?

标签 react-native jestjs react-navigation higher-order-components react-testing-library

我正在用 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 我和我的测试set up a custom render method像这样:
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.

最佳答案

根据 Kubilay 的回答,我是这样解决的:

jest.mock('react-navigation', () => ({
  withNavigation: Component => props => (
    <Component navigation={{ navigate: jest.fn() }} {...props} />
  ),
  SafeAreaView: ({ children }) => <>{children}</>,
}));

afterAll(() => {
  jest.restoreAllMocks();
});

我不得不 mock withNavigation以及 SafeAreaView .

这仍然是一个非常不满意的方式。如果有人知道如何在自定义渲染方法中注入(inject)正确的 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 };

关于react-native - react 导航 : How to test components that use the withNavigation HOC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57525516/

相关文章:

javascript - 组件 'div' 的 View 配置 getter 回调必须是一个函数(收到 'undefined' )。确保组件名称以大写字母开头

javascript - WebView 适用于 react-native-router-flux NavBar 但不适用于 shoutem/ui NavigationBar

reactjs - 在 useEffect Hook 中进行的异步调用的测试结果

node.js - 是否可以在 Node 中为没有 catch block 的 Promise 编写一个 Jest 单元测试?

react-native - 为 react-navigation DrawerNavigator 设置滑动区域宽度

reactjs - React-navigation:检测新屏幕是否完全聚焦

android - 无法运行应用程序显示安装应用程序失败

javascript - 为什么函数在 AsyncStorage 完成之前运行

javascript - 为什么 Jest 测试命名约定是这样的?

react-native - 屏幕位于底部 Material 选项卡栏后面