【问题标题】:How to test project when 3rd party modules used aren't transpiled未转译使用的 3rd 方模块时如何测试项目
【发布时间】:2016-09-12 02:27:11
【问题描述】:

我正在尝试使用酶来测试我的 React Native 项目,并且已按照设置说明进行操作。

https://github.com/airbnb/enzyme/blob/master/docs/guides/react-native.md

  "scripts": {
     "start": "node node_modules/react-native/local-cli/cli.js start",
     "test": "mocha --require react-native-mock/mock.js --compilers js:babel-core/register --recursive test/**/*.js"
  },

这工作正常并且我自己的代码被正确转译,但是当我包含一个不转译其代码的模块时(例如https://github.com/aksonov/react-native-router-flux),我的测试拒绝运行,因为它在这些模块中的导入语句中出错。

如何让 babel 转译这些模块,或者有其他方法可以让我的测试运行吗?

更新

似乎未转译的 3rd 方模块在 React Native 中相当普遍,因为 React Native 本身并未转译。

解决方案似乎是强制转译和使用 react-native-mock 的组合。 https://github.com/facebook/react-native/issues/5392

但是,由于 NavigationExperimental 未被模拟,我在 react-native-router-flux 方面遇到了更多问题。

相关链接是:

https://github.com/lelandrichardson/react-native-mock/issues/23 https://github.com/lelandrichardson/react-native-mock/issues/22 https://github.com/lelandrichardson/react-native-mock/pull/34

如果我找到解决方案,我会在这里更新。

更新 2

我在下面提供了我当前的解决方法,以防有人发现它有用。

https://stackoverflow.com/a/37655424/168012

【问题讨论】:

  • 你从 npm 安装了react-native-router-flux?而且不是 ES5?
  • @JMM 是的。我只需要仔细检查,因为我现在直接从一个分支中拉出,但是是的,从 NPM 安装的是 ES6。最近更改的 PR 已被放弃,因此我正在寻找替代解决方案 github.com/aksonov/react-native-router-flux/pull/649

标签: npm react-native mocha.js babeljs enzyme


【解决方案1】:

这是我的 testHelper.js 来处理 react-native- 3th 方模块

require('babel-polyfill');
require('react-native-mock/mock');

// require('babel-core/register')({
//   ignore: function(packageName) {
//     if (packageName.match(/node_modules/)) {
//       return !(packageName.match(/react-native-vector-icons/)
//         || packageName.match(/react-native-animatable/)
//         || packageName.match(/react-native-router-flux/)
//         || packageName.match(/react-native-tab-navigator/)
//       );
//     }
//     return false;
//   }
// });

var fs = require('fs');
var path = require('path');

function getBabelRC() {
  var rcpath = path.join(__dirname, '.babelrc');
  var source = fs.readFileSync(rcpath).toString();
  return JSON.parse(source);
}

var config = getBabelRC();

config.ignore = function(filename) {
  if (!(/\/node_modules\//).test(filename)) {
    console.log(filename, 'FALSE');
    return false; // if not in node_modules, we want to compile it
  } else if ((/\/node_modules\/react-native.*\//).test(filename)) {
    // its RN source code, so we want to compile it
    console.log(filename, 'FALSE');
    return false;
  } else {
    console.log(filename, 'TRUE');
    // it's in node modules and NOT RN source code
    return true;
  }
};

require("babel-register")(config);

global.__DEV__ = true;


// var chai = require('chai');
// var dirtyChai = require('dirty-chai');
// chai.use(dirtyChai);

import chai from 'chai';
import dirtyChai from 'dirty-chai';
// import chaiImmutable from 'chai-immutable';

chai.use(dirtyChai);
//chai.use(chaiImmutable);

import mockery from "mockery";

mockery.enable();
mockery.registerMock('./menu_burger.png', 0);

这是我的 npm 测试

"test": "node_modules/.bin/mocha --compilers js:babel-core/register --require testHelper.js **/__test__/*.js",

【讨论】:

    【解决方案2】:

    我目前的解决方案如下(鉴于目前 ReactNativeMock 中不支持 NavigationExperimental):

    package.json

    "scripts": {
        ...
        "test": "mocha --require test/init.js --recursive test/**/*.js"
      },
    

    /test/init.js

    require('react-native-mock/mock');
    
    require("babel-register")({
        only: [
            "/node_modules/react-native-tab-navigator/*.js",
            "/node_modules/react-native-router-flux/*.js",
            "/node_modules/react-native-router-flux/src/*.js",
            "/node_modules/react-native-tabs/*.js",
            "/node_modules/react-native-button/*.js",
            "/node_modules/react-native-swipeout/*.js",
            "/app/**/*",
            "/test/**/*",
        ]
    });
    
    import mockery from 'mockery';
    mockery.enable();
    mockery.registerMock('react-native-router-flux', {Actions:{}});
    

    【讨论】:

      【解决方案3】:

      您可以尝试创建自己的脚本来调用 require 钩子而不是 --compilers js:babel-core/register(顺便说一句,最好使用 babel-register 包)并使用 only|ignore 选项:

      // init.js
      require("babel-register")({
        only: [
          "/my-app-dir/src/**/*",
          "/my-app-dir/node_modules/react-native-router-flux/**/*",
        ]
      });
      
      mocha --require ./init.js
      

      不过,这通常是一种非常可疑的发布包的方式。这是假设 .babelrc 与包一起发布。即便如此,由于它引用的东西被称为devDependencies,你似乎需要手动进入它的文件夹并安装它们。

      【讨论】:

      • 进一步调查显示这似乎是 React Native 模块的常见做法,因为 React Native 本身没有被转译。
      猜你喜欢
      • 1970-01-01
      • 2016-10-03
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 2021-10-02
      • 1970-01-01
      相关资源
      最近更新 更多