【问题标题】:use webpack plugin with Mocha tests在 Mocha 测试中使用 webpack 插件
【发布时间】:2018-10-05 11:29:58
【问题描述】:

我使用 create-react-app 创建了一个应用程序,并弹出了配置。在webpack.config.dev.jswebpack.config.prod.js 中,我已经像这样配置了NormalModuleReplacementPlugin

new webpack.NormalModuleReplacementPlugin(/(.*)CUSTOMER(\.*)/, function(resource) {
  const customerName = process.env.REACT_APP_CUSTOMER;
  resource.request = resource.request.replace(/CUSTOMER/, customerName);
})

这样做的目的是替换诸如

之类的导入
import config from '../config/customer/CUSTOMER';

import config from '../config/customer/foo';

REACT_APP_CUSTOMER 变量的值设置为“foo”时。

当应用程序运行时这工作正常,但我有一些通过 package.json 中的 test-mocha 脚本运行的 Mocha 测试

"scripts": {
  "test-mocha": "NODE_ENV=test node_modules/.bin/mocha --require babel-register --recursive test"
}

运行此测试时,不会发生导入替换。似乎以下任何一种都可以解决问题:

  • 配置运行测试时使用的NormalModuleReplacementPlugin
  • 找到一种方法,在运行测试时为 config 提供模拟

【问题讨论】:

    标签: reactjs webpack mocha.js


    【解决方案1】:

    看看mocha-webpack。如文档中所述,它基本上运行 webpack test.js output.js && mocha output.js 并进行了一些优化。所以,在npm i -D mocha-webpack 之后,你的scripts 应该是这样的:

    "scripts": {
      "test-mocha": "NODE_ENV=test node_modules/.bin/mocha-webpack --recursive test"
    }
    

    您可以尝试的另一个选项是使用mock-require,它负责模拟node.js 模块。在您的情况下,您需要要求 mock-helper.js:

    "test-mocha": "NODE_ENV=test node_modules/.bin/mocha -r babel-register -r ./test/mock-helper.js --recursive test"

    ./test/mock-helper.js 应该是这样的:

    const mock = require('mock-require');
    const defaultCustomer = require('../config/customer/default');
    const fooCustomer = require('../config/customer/foo');
    
    const customerMock = (function () {
      switch (process.env.REACT_APP_CUSTOMER) {
        case 'foo': return fooCustomer;
        default: return defaultCustomer;
      }
    }())
    
    mock('../config/customer/CUSTOMER', customerMock);
    

    希望对你有帮助。

    【讨论】:

    • 我尝试使用mock-require,但我仍然收到错误Error: Cannot find module '../config/customer/CUSTOMER'mock-require 是否能够模拟 import 而不是 require 中包含的模块?
    • 我创建了一个repo 并使用mock-require 工作示例。希望对你有帮助
    【解决方案2】:

    我选择了一个简单/明显的解决方案:

    创建一个虚拟文件config/customer/CUSTOMER.js,其中包含最低预期配置,例如

    export default {
      customerName: 'Dummy'
    }
    

    当测试运行时,导入例如

    import config from '../config/customer/CUSTOMER';
    

    将不再失败,因为该模块现已存在。

    【讨论】:

      【解决方案3】:

      我建议你使用Karmajs

      Karmajs 是一个测试运行器,因此您可以将其配置为使用 mocha 运行测试,也可以使用 webpack 预处理您的测试,因此所有预处理(对于 NormalModuleReplacementPlugin 和任何其他)都已完成当您使用 Karma 执行测试时,可以使用 via webpack 配置。

      基本上,在您的应用程序中安装 Karma 及其相关软件包

      yarn add karma karma-chai-plugins karma-chrome-launcher karma-cli karma-coverage karma-mocha karma-mocha-reporter karma-sinon-chai karma-sourcemap-loader karma-webpack
      

      创建karma.conf.js

      const webpackConfig = require('./webpack.config');
      const webpack = require('webpack');
      webpackConfig.devtool = 'inline-source-map';
      webpackConfig.plugins = [
        new webpack.ProvidePlugin({
          'es6-promise': 'es6-promise',
        }),
      ];
      
      module.exports = function (config) {
        config.set({
          browsers: [ 'Chrome' ],
          // karma only needs to know about the test bundle
          files: [
            '../node_modules/babel-polyfill/dist/polyfill.js',
            'karma.globals.js',
            'tests.bundle.js',
          ],
          frameworks: [ 'chai', 'mocha' ],
          // run the bundle through the webpack and sourcemap plugins
          preprocessors: {
            'tests.bundle.js': [ 'webpack', 'sourcemap' ],
          },
          // reporters: [ 'mocha', 'coverage' ],
          reporters: [ 'mocha' ],
          // coverageReporter: {
          //   type: 'text-summary',
          //   includeAllSources: true
          // },
          singleRun: false,
          autoWatch: true,
          // webpack config object
          webpack: webpackConfig,
          webpackMiddleware: {
            noInfo: true,
          },
        });
      };
      

      创建tests.bundle.js 为您的所有测试文件运行测试,在此示例中,我们所有的测试文件都有一个文件扩展名.spec.js 并位于./src 目录中。

      tests.bundle.js

      const context = require.context('./src', true, /\.spec\.js$/);
      context.keys().forEach(context);
      
      export default context;
      

      要设置需要在所有应用/测试中可用的全局变量,可以使用karma.globals.js 文件进行设置。

      karma.globals.js

      const __DEV__ = false;
      
      const INITIAL_STATE = {
        name: 'My App',
        version: 'v2.5.6'
      };
      

      以上配置完成后,您可以通过执行以下命令从创建 karma.config.js 和 package.json 的目录中运行所有测试。

      yarn karma start
      

      注意:测试也可以配置为在无头浏览器(如 phantomjs)中执行,在此示例中,我们使用 Chrome 浏览器运行测试。

      【讨论】:

        【解决方案4】:

        您可以将其添加到您的测试脚本中:

        REACT_APP_CUSTOMER=foo
        

        所以你的测试脚本变成了:

        "test-mocha": "NODE_ENV=test REACT_APP_CUSTOMER=foo node_modules/.bin/mocha --require babel-register --recursive test"
        

        这会起作用,因为它会在 process.env 中设置您想要的值, 我不确定,但我认为这是唯一合理的方法,因为您在运行测试时正在模拟您的环境。

        【讨论】:

        • 为了使导入替换工作,需要启用NormalModuleReplacementPlugin 并且需要设置REACT_APP_CUSTOMER 变量。这只适用于后者。
        • @Dónal 我想你可以使用mocha-webpack。正如它在其文档中所说,它会使用您的 webpack 配置预构建您的测试文件,因此 NormalModuleReplacementPlugin 将在您的测试中启用,因为它们是使用您自己的配置文件构建的
        猜你喜欢
        • 2016-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多