Jest: неожиданный экспорт токенов с реагирующей навигацией - PullRequest
2 голосов
/ 04 марта 2020

Потратив два дня на исследования, у меня наконец закончились идеи.

Проблема в том, что компонент использует withNavigation из React-Navigation.

Когда я запускаю Jest, он жалуется на неожиданный экспорт токена (React-Navigation), указывая withNavigation.

enter image description here

Поскольку существует такая же проблема с другими сторонними библиотеками (такими как Native Base), я пришел к выводу, что должна быть проблема с transformIgnorePatterns. Например, я попробовал это решение среди многих других, более или менее похожих. Я также попытался настроить babel.config, как это было предложено в другом посте на GitHub. Ничего не работает! Может быть, у кого-то есть идеи? Обратите внимание, что я использую TypeScript.

Вот часть Jest, если мой package.json:

  ...
  "jest": {
    "preset": "react-native",
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js",
      "\\.(ts|tsx)$": "ts-jest"
    },
    "globals": {
      "ts-jest": {
        "tsConfig": "tsconfig.jest.json"
      }
    },
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!react-native|native-base|react-navigation|react-native-fabric)"
    ],
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$"
  }

jest.config. js:

module.exports = {
  preset: 'react-native',
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};

tsconfig.jest. json:

{
  "extends": "./tsconfig",
  "compilerOptions": {
    "jsx": "react",
    "module": "commonjs"
  }
}

tsconfig. json:

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "isolatedModules": true,
    "noImplicitAny": true,
    "jsx": "react",
    "lib": ["es6"],
    "moduleResolution": "node",
    "noEmit": true,
    "strict": true,
    "target": "esnext"
  },
  "exclude": [
    "node_modules",
    "babel.config.js",
    "metro.config.js",
    "jest.config.js"
  ]
}

babel.config. js:

module.exports = {
  presets: [
    'module:metro-react-native-babel-preset',
    '@babel/preset-typescript',
  ],
};

Компонент (Тест):

imports ...

type Props = {}

const Test: React.FC<Props> = ({}) => {
  return (
    <View testID="test" style={styles.container}>
      <View>
        <Text testID="home">Home</Text>
        <ButtonNavigate title="Home" navigateTo="About" />
      </View>
    </View>
  );
};

export default withNavigation(Test);

И тест:

import React from 'react';
import {render, fireEvent} from 'react-native-testing-library';

import Test from '../Test';

// NativeAnimatedHelper is not mocked by default on react native's jest setup file.
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
//jest.mock('react-navigation', () => ({withNavigation: component => component}));

describe('Test', () => {
  test('rendering a component that uses withNavigation', () => {
    const {getByTestId} = render(
      <Test navigation={navigation}></Test>,
    );
    expect(getByTestId('test').toBeDefined());
  });
});

Заранее спасибо, если кто-нибудь может помочь.

1 Ответ

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

Это работает для меня:

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

Скажите, работает ли оно и для вас.

...