React Native Expo App:如何使其运行Jest测试

时间:2019-02-13 17:55:02

标签: unit-testing react-native npm jestjs expo

因此,在使用Expo创建React Native应用程序时,Jest现在似乎已经被打破了。

复制步骤:

  1. `expo init'
  2. 选择标签页。
  3. cd进入您的应用。
  4. 运行npm test 失败

我用Google搜索并尝试了以下修复程序:

A)添加jest.config.js

module.exports = {
  preset: 'jest-expo',
  transform: {
    '\\.js$': '<rootDir>/node_modules/react-native/jest/preprocessor.js',
  }
};

B)将react-native预处理程序复制到您自己的`jest.preprcessor.js'文件中:

 transform: {
    /*
     * Stop jest from falling over on its face.
     * cf. https://github.com/expo/expo/issues/2595#issuecomment-440966998
     * cf. https://github.com/facebook/react-native/issues/22175#issuecomment-436959462
     */
    '\\.js$': '<rootDir>/jest.preprocessor.js',
  },

C)更改“测试”脚本部分

来自:

"test": "node_modules/.bin/jest"

收件人:

"test": "node ./node_modules/jest/bin/jest.js"

因此没有任何效果。所有方法都会导致部分或全部测试失败。

有人知道如何开玩笑与Expo 32一起工作吗?

编辑: Bruno's answer有效。此外,在运行node_modules之前,请确保删除package-lock.jsonyarn。此外,您不需要jest.config.js。而且您也不需要Bruno的babel.config.js。这是我的:

module.exports = function(api) {
    api.cache(true);
    return {
        presets: ['babel-preset-expo'],
    };
};

太奇怪了,它不适用于npm

PS,这是预处理程序代码,因此您无需搜索它:

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 */

/* eslint-env node */

'use strict';

const {transformSync: babelTransformSync} = require('@babel/core');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
 * found when Flow v0.54 was deployed. To see the error delete this comment and
 * run Flow. */
const babelRegisterOnly = require('metro-babel-register');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
 * found when Flow v0.54 was deployed. To see the error delete this comment and
 * run Flow. */
const createCacheKeyFunction = require('fbjs-scripts/jest/createCacheKeyFunction');
const generate = require('@babel/generator').default;

const nodeFiles = RegExp(
  [
    '/local-cli/',
    '/metro(?:-[^/]*)?/', // metro, metro-core, metro-source-map, metro-etc
  ].join('|'),
);
const nodeOptions = babelRegisterOnly.config([nodeFiles]);

babelRegisterOnly([]);

/* $FlowFixMe(site=react_native_oss) */
const transformer = require('metro/src/reactNativeTransformer');
module.exports = {
  process(src /*: string */, file /*: string */) {
    if (nodeFiles.test(file)) {
      // node specific transforms only
      return babelTransformSync(src, {
        filename: file,
        sourceType: 'script',
        ...nodeOptions,
        ast: false,
      }).code;
    }

    const {ast} = transformer.transform({
      filename: file,
      localPath: file,
      options: {
        ast: true, // needed for open source (?) https://github.com/facebook/react-native/commit/f8d6b97140cffe8d18b2558f94570c8d1b410d5c#r28647044
        dev: true,
        inlineRequires: true,
        minify: false,
        platform: '',
        projectRoot: '',
        retainLines: true,
        sourceType: 'unambiguous', // b7 required. detects module vs script mode
      },
      src,
      plugins: [
        [require('@babel/plugin-transform-block-scoping')],
        // the flow strip types plugin must go BEFORE class properties!
        // there'll be a test case that fails if you don't.
        [require('@babel/plugin-transform-flow-strip-types')],
        [
          require('@babel/plugin-proposal-class-properties'),
          // use `this.foo = bar` instead of `this.defineProperty('foo', ...)`
          {loose: true},
        ],
        [require('@babel/plugin-transform-computed-properties')],
        [require('@babel/plugin-transform-destructuring')],
        [require('@babel/plugin-transform-function-name')],
        [require('@babel/plugin-transform-literals')],
        [require('@babel/plugin-transform-parameters')],
        [require('@babel/plugin-transform-shorthand-properties')],
        [require('@babel/plugin-transform-react-jsx')],
        [require('@babel/plugin-transform-regenerator')],
        [require('@babel/plugin-transform-sticky-regex')],
        [require('@babel/plugin-transform-unicode-regex')],
        [
          require('@babel/plugin-transform-modules-commonjs'),
          {strict: false, allowTopLevelThis: true},
        ],
        [require('@babel/plugin-transform-classes')],
        [require('@babel/plugin-transform-arrow-functions')],
        [require('@babel/plugin-transform-spread')],
        [require('@babel/plugin-proposal-object-rest-spread')],
        [
          require('@babel/plugin-transform-template-literals'),
          {loose: true}, // dont 'a'.concat('b'), just use 'a'+'b'
        ],
        [require('@babel/plugin-transform-exponentiation-operator')],
        [require('@babel/plugin-transform-object-assign')],
        [require('@babel/plugin-transform-for-of'), {loose: true}],
        [require('@babel/plugin-transform-react-display-name')],
        [require('@babel/plugin-transform-react-jsx-source')],
      ],
    });

    return generate(
      ast,
      {
        code: true,
        comments: false,
        compact: false,
        filename: file,
        retainLines: true,
        sourceFileName: file,
        sourceMaps: true,
      },
      src,
    ).code;
  },

  getCacheKey: createCacheKeyFunction([
    __filename,
    require.resolve('metro/src/reactNativeTransformer'),
    require.resolve('@babel/core/package.json'),
  ]),
};

我的依赖项:

"dependencies": {
    "@expo/samples": "2.1.1",
    "expo": "^32.0.0",
    "formik": "^1.5.0",
    "i18n-js": "^3.2.1",
    "prop-types": "^15.7.1",
    "react": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
    "react-navigation": "^3.0.9",
    "yup": "^0.26.10"
  },
  "devDependencies": {
    "babel-eslint": "^10.0.1",
    "babel-preset-expo": "^5.0.0",
    "eslint": "^5.13.0",
    "eslint-plugin-import": "^2.16.0",
    "eslint-plugin-jsx-a11y": "^6.2.1",
    "eslint-plugin-react": "^7.12.4",
    "eslint-plugin-react-native": "^3.6.0",
    "eslint-plugin-react-native-a11y": "^1.2.0",
    "eslint-plugin-simple-import-sort": "^3.0.0",
    "jest-expo": "^32.0.0",
    "react-native-elements": "^1.0.0",
    "react-native-testing-library": "^1.5.0"
  },

1 个答案:

答案 0 :(得分:4)

您的dependeciesdevDependencies看起来不错。

  • 首先,安装yarn。请按照此link的说明进行操作。
  • 第二,您必须更改package.json中的一些内容。像这样:
"scripts": {
    "test": "jest",
    ...
  },
"jest": {
    "preset": "jest-expo",
    "transform": {
      "^.+\\.js$": "babel-jest"
  },
}
  • 第三,确保正确设置了babel.config.js。这是我的项目中运行Expo's 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