如何配置 Jest 以使用 Expo SDK 32

How to configure Jest to work with Expo SDK 32

我有一个 Expo 应用程序并且正在使用 SDK 28。我的团队决定我们应该更新到最新版本,这意味着更新 React Native(因为最新的 SDK 使用 RN 0.57)和 Babel。

当我们更新我们的依赖项并修复我们的配置文件时,Jest 开始给我们这个错误:

TypeError: Cannot read property 'fetch' of undefined

      at node_modules/react-native/Libraries/vendor/core/whatwg-fetch.js:6:12
      at Object.<anonymous> (node_modules/react-native/Libraries/vendor/core/whatwg-fetch.js:486:3)
      at Object.<anonymous> (node_modules/jest-expo/src/setup.js:125:16)

调试几天后我发现这与 babel-jest 的预处理器无法正常工作有关,即使我按照他们的安装 docs.

我仔细研究了一下,发现 GitHub Issue thread 中有一个解决方法。

实施解决方法,并将 babel-hoist 添加到我的 babel.config.js,以便测试开始 运行。

然而,Jest 的行为很不稳定,覆盖率数据也不正确(即使我们确实对它们进行了测试,它也将一些行计算为未覆盖)。

我想知道如何正确配置 Jest 以兼容 Expo SDK 32。

这些是相关的配置文件(设置为使用前面提到的解决方法)。

package.json*

"dependencies": {
    "@babel/preset-env": "^7.3.1",
    "@expo/vector-icons": "6.3.1",
    "expo": "^32.0.0",
    "prop-types": "15.6.2",
    "react": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
    "sentry-expo": "~1.9.0"
    ...
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "babel-eslint": "9.0.0",
    "babel-plugin-jest-hoist": "^24.0.0",
    "babel-preset-expo": "^5.0.0",
    "enzyme": "3.8.0",
    "enzyme-adapter-react-16": "^1.8.0",
    "jest-expo": "^32.0.0",
    "metro-react-native-babel-preset": "^0.51.1",
    "react-dom": "^16.5.1",
    ...
  },
"jest": {
    "preset": "jest-expo",
    "transform": {
      "^.+\.js$": "<rootDir>/jest.preprocessor.js"
    },
    "setupFiles": [
      "<rootDir>/src/jest.setup.js"
    ],
  ...
}

* 省略了一些依赖。

babel.config.js

module.exports = {
  presets: [
    'babel-preset-expo',
    'module:metro-react-native-babel-preset',
    'module:react-native-dotenv',
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        },
      },
    ],
  ],
  sourceMaps: true,
  plugins: [
    'jest-hoist',
    '@babel/transform-react-jsx-source',
  ],
};

Expo 自动设置 jest。 我认为你必须做 'Expo init newProject',然后阅读 .babelrc 和 package.json

以下是 expo init 的结果。 效果不错。

// 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": "^32.0.0",
    "react": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
    "react-navigation": "^3.0.9"
  },
  "devDependencies": {
    "babel-preset-expo": "^5.0.0",
    "jest-expo": "^32.0.0"
  },
  "private": true
}
// babel.config.js
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
  };
};

这就是为我解决问题的原因:

  • 首先,安装 yarn。按照此 link 获取说明。
  • 其次,确保您的 package.json 看起来像这样:
"dependencies": {
    "@expo/vector-icons": "9.0.0",
    "expo": "^32.0.0",
    "prop-types": "15.6.2",
    "react": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
    ...
  },

"devDependencies": {
    "babel-preset-expo": "^5.0.0",
    "jest-expo": "^32.0.0",
    ...
  }
"scripts": {
    "test": "jest",
    ...
  },
"jest": {
    "preset": "jest-expo",
    "transform": {
      "^.+\.js$": "babel-jest"
  },
}
  • 第三,确保您的 babel.config.js 设置正确。这是我项目 运行ning Expo 的 SDK 32 中的一个:
module.exports = function (api) {
  api.cache(true);
  return {
    presets: [
      'babel-preset-expo',
      'module:react-native-dotenv',
    ],
    sourceMaps: true,
    plugins: [
      '@babel/transform-react-jsx-source',
    ],
  };
};
  • 最后,使用 yarn 安装您的软件包 (yarn install) 并 运行 您的测试 yarn test.