如何配置 Jest 以使用 Expo SDK 32

Posted

技术标签:

【中文标题】如何配置 Jest 以使用 Expo SDK 32【英文标题】:How to configure Jest to work with Expo SDK 32 【发布时间】:2019-06-28 15:48:15 【问题描述】:

我有一个 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',
  ],
;

【问题讨论】:

【参考方案1】:

这就是为我解决问题的方法:

首先,安装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 设置正确。这是我运行 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

【讨论】:

为我工作,但你能解释一下为什么它适用于 yarn 而不适用于 npm 吗? @baraber 不太确定,但我猜npm 下载了错误/旧的包,而yarn 安装了正确的包。据我所知,Expo 开发人员使用 Yarn,因此他们必须仅使用 yarn 测试 SDK 32,这导致新版本和 npm 安装出现这些问题。 这可能是有道理的,因为它看起来像一些依赖问题。【参考方案2】:

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'],
  ;
;

【讨论】:

您为我指明了正确的方向:这似乎是 NPM 的问题。当我创建一个新的示例项目时,我注意到它使用 Yarn 来下载依赖项。如果我删除了node_moduels 文件夹并使用了npm install,那么之后测试就会开始中断。

以上是关于如何配置 Jest 以使用 Expo SDK 32的主要内容,如果未能解决你的问题,请参考以下文章

开玩笑:测试套件无法运行(Expo SDK 需要 Expo 才能运行)

在未弹出 Redux 的情况下测试 Jest React-Native Expo CRNA

SyntaxError:无法在模块外使用 import 语句:运行 Jest-expo 测试时

React Native Expo App:如何让它运行 Jest 测试

Expo SDK32 undefined 不是对象(评估 '_expo2.default.KeepAwake')

Jest-expo 测试不运行