Как протестировать компонент React Native с помощью NavigationEvents в jest - PullRequest
1 голос
/ 08 марта 2020

Как мне написать юнит-тест jest для собственного компонента реагирования, который содержит подкомпонент NavigationEvents.

Я пробовал решения, предлагаемые в вопросах здесь и здесь без успеха.

Я получаю ошибку

    console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9215
      The above error occurred in the <Context.Consumer> component:
          in withNavigation(NavigationEvents) (created by MyComponent)
          in View (created by View)
          in View (created by MyComponent)
          in MyComponent

      Consider adding an error boundary to your tree to customize error handling behavior.

  ● MyComponent test › renders

    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.

Ниже приведен минимальный пример, вызывающий ошибку.

import 'react-native';
import { View } from 'react-native';
import { NavigationEvents } from 'react-navigation';
import React from 'react';
import renderer from 'react-test-renderer';

class MyComponent extends React.Component {

    constructor(props) {
      super(props);
    }

    render() {
        return (
          <View>
            <NavigationEvents/>
          </View>
        );}
  }

describe('MyComponent test', () => {
    it('renders', () => {

        jest.mock('react-navigation', () =>({
            NavigationEvents: 'mockNavigationEvents',
            withNavigation: component => component
          }));
        const navigation = { navigate: jest.fn() };

        renderer.create(<MyComponent navigation={navigation}/>);
    });
});

Редактировать

По запросу в комментариях добавлено package.json ниже:


{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "eject": "expo eject",
    "test": "node ./node_modules/jest/bin/jest.js --watchAll"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@expo/samples": "2.1.1",
    "@expo/vector-icons": "^10.0.0",
    "expo": "^35.0.0",
    "expo-camera": "~7.0.0",
    "expo-sqlite": "^7.0.0",
    "moment": "^2.24.0",
    "react": "16.8.3",
    "react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
    "react-native-action-button": "^2.8.5",
    "react-native-calendar-picker": "^6.0.0",
    "react-native-dialog": "^5.6.0",
    "react-native-dotenv": "^0.2.0",
    "react-native-dynamic-search-bar": "^0.1.11",
    "react-native-elements": "^1.1.0",
    "react-native-gesture-handler": "~1.3.0",
    "react-native-keyboard-aware-scroll-view": "^0.9.1",
    "react-native-modal-datetime-picker": "^7.4.0",
    "react-native-paper": "^2.15.2",
    "react-native-progress-circle": "^2.1.0",
    "react-native-search-bar": "^3.4.2",
    "react-native-vector-icons": "^6.4.2",
    "react-navigation": "^3.0.9",
    "expo-constants": "~7.0.0",
    "expo-file-system": "~7.0.0"
  },
  "devDependencies": {
    "babel-preset-expo": "^7.0.0",
    "jest-expo": "^35.0.0"
  },
  "private": true
}

expo-cli версия

$ expo-cli -V
3.13.1

1 Ответ

1 голос
/ 15 марта 2020

Проблема в том, что jest.mock должен быть вне функций describe и it. Вам не нужно вручную макетировать navigation объект, поскольку вы насмехаетесь над функцией withNavigation HO C:

// Setup mocks outside describe and it functions
jest.mock('react-navigation', () =>({
  NavigationEvents: 'mockNavigationEvents',
  withNavigation: component => component
}));

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <View>
        <NavigationEvents/>
      </View>
    );
  }
}

describe('MyComponent test', () => {
  it('renders', () => {
    renderer.create(<MyComponent/>);
  });
});

И тест renders проходит:

Jest test renders

Я предлагаю вам включить все эти макеты в файл и установить setupFilesAfterEnv в package.json:

package.json > jest:

"jest": {
  "preset": "jest-expo"
  "setupFilesAfterEnv": ["./path/to/jestInit.js"]
},

jestInit.js:

jest.mock('react-navigation', () =>({
  NavigationEvents: 'mockNavigationEvents',
  withNavigation: component => component
}));

Таким образом, вы получите эти макеты для каждого файла теста Jest без необходимости включать макеты внутри каждого теста файл.

...