在 Mocha 测试中使用 webpack 插件
use webpack plugin with Mocha tests
我已经使用 create-react-app 创建了一个应用程序,并弹出了配置。在 webpack.config.dev.js
和 webpack.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
脚本
"scripts": {
"test-mocha": "NODE_ENV=test node_modules/.bin/mocha --require babel-register --recursive test"
}
当此测试 运行s 时,导入替换不会发生。似乎以下任一方法都可以解决问题:
- 配置
NormalModuleReplacementPlugin
在测试 运行 时使用
- 想办法在测试 运行
时为 config
提供模拟
您可以将此添加到您的测试脚本中:
REACT_APP_CUSTOMER=foo
所以你的测试脚本变成:
"test-mocha": "NODE_ENV=test REACT_APP_CUSTOMER=foo node_modules/.bin/mocha --require babel-register --recursive test"
这会起作用,因为它会在 process.env
中设置您想要的值,
我不确定,但我认为这是唯一合理的方法,因为你在 运行 测试时模拟你的环境。
看看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);
希望对您有所帮助。
我选择了 simple/obvious 解决方案:
创建一个包含最低预期配置的虚拟文件config/customer/CUSTOMER.js
,例如
export default {
customerName: 'Dummy'
}
当测试 运行 时,导入
import config from '../config/customer/CUSTOMER';
将不再失败,因为此模块现已存在。
我建议你使用 Karmajs
Karmajs 是一个测试 运行ner,所以你可以配置它使用 mocha 进行 运行ning 测试,你也可以用 webpack 预处理你的测试,所以所有的预处理(对于 NormalModuleReplacementPlugin
和任何其他)当您使用 Karma 执行测试时,可以通过 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,
},
});
};
为所有测试文件的 运行ning 测试创建 tests.bundle.js
,在这个例子中,我们所有的测试文件都有文件扩展名 .spec.js
并且位于 ./src
目录。
tests.bundle.js
const context = require.context('./src', true, /\.spec\.js$/);
context.keys().forEach(context);
export default context;
要设置需要在所有 app/tests 中可用的全局变量,可以使用 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 浏览器来 运行 我们的测试。
我已经使用 create-react-app 创建了一个应用程序,并弹出了配置。在 webpack.config.dev.js
和 webpack.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
脚本
"scripts": {
"test-mocha": "NODE_ENV=test node_modules/.bin/mocha --require babel-register --recursive test"
}
当此测试 运行s 时,导入替换不会发生。似乎以下任一方法都可以解决问题:
- 配置
NormalModuleReplacementPlugin
在测试 运行 时使用
- 想办法在测试 运行 时为
config
提供模拟
您可以将此添加到您的测试脚本中:
REACT_APP_CUSTOMER=foo
所以你的测试脚本变成:
"test-mocha": "NODE_ENV=test REACT_APP_CUSTOMER=foo node_modules/.bin/mocha --require babel-register --recursive test"
这会起作用,因为它会在 process.env
中设置您想要的值,
我不确定,但我认为这是唯一合理的方法,因为你在 运行 测试时模拟你的环境。
看看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);
希望对您有所帮助。
我选择了 simple/obvious 解决方案:
创建一个包含最低预期配置的虚拟文件config/customer/CUSTOMER.js
,例如
export default {
customerName: 'Dummy'
}
当测试 运行 时,导入
import config from '../config/customer/CUSTOMER';
将不再失败,因为此模块现已存在。
我建议你使用 Karmajs
Karmajs 是一个测试 运行ner,所以你可以配置它使用 mocha 进行 运行ning 测试,你也可以用 webpack 预处理你的测试,所以所有的预处理(对于 NormalModuleReplacementPlugin
和任何其他)当您使用 Karma 执行测试时,可以通过 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,
},
});
};
为所有测试文件的 运行ning 测试创建 tests.bundle.js
,在这个例子中,我们所有的测试文件都有文件扩展名 .spec.js
并且位于 ./src
目录。
tests.bundle.js
const context = require.context('./src', true, /\.spec\.js$/);
context.keys().forEach(context);
export default context;
要设置需要在所有 app/tests 中可用的全局变量,可以使用 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 浏览器来 运行 我们的测试。