【问题标题】:React Navigation: How to test components that use the withNavigation HOC?React Navigation:如何测试使用 withNavigation HOC 的组件?
【发布时间】:2019-12-22 19:55:39
【问题描述】:

我正在使用 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.

【问题讨论】:

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


    【解决方案1】:

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

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

    我不得不模拟 withNavigationSafeAreaView

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

    【讨论】:

    • ReferenceError: afterAll 没有定义
    • @KishanVaghela 这是一个 linting 错误。您需要定义 Jest 的全局变量。
    • 也适合我。谢谢!
    【解决方案2】:

    你应该像这样模拟 react-navigation:

    jest.mock("react-navigation", ({ withNavigation: (component) => component })
    

    然后将 props 传递给您的组件:

    const mockProps = {
        navigation: { navigate: jest.fn() }
    }
    
    wrapper = shallow(<LoginScreen {...mockProps}/>)
    

    【讨论】:

    • 感谢您的帮助。这行不通。我更新了我的问题。
    猜你喜欢
    • 2019-04-08
    • 1970-01-01
    • 2019-01-06
    • 2018-02-15
    • 2019-09-30
    • 2018-12-31
    • 2019-07-04
    • 2020-09-09
    • 2021-08-13
    相关资源
    最近更新 更多