I've used create-react-app to create an app, and ejected the config. In webpack.config.dev.js
and webpack.config.prod.js
, I've configured the NormalModuleReplacementPlugin
like so:
new webpack.NormalModuleReplacementPlugin(/(.*)CUSTOMER(\.*)/, function(resource) {
const customerName = process.env.REACT_APP_CUSTOMER;
resource.request = resource.request.replace(/CUSTOMER/, customerName);
})
The purpose of this is to replace imports such as
import config from '../config/customer/CUSTOMER';
with
import config from '../config/customer/foo';
when the value of the REACT_APP_CUSTOMER
variable is set to "foo".
This works fine when the app runs, but I have some Mocha tests that are run via a test-mocha
script in package.json
"scripts": {
"test-mocha": "NODE_ENV=test node_modules/.bin/mocha --require babel-register --recursive test"
}
When this test runs, the import replacement doesn't happen. It seems either of the following would solve the problem:
NormalModuleReplacementPlugin
to be used when the tests are runconfig
when the tests are runI settled on a simple/obvious solution:
Create a dummy file config/customer/CUSTOMER.js
that contains the minimum expected configuration, e.g.
export default {
customerName: 'Dummy'
}
when the tests are run, an import such as
import config from '../config/customer/CUSTOMER';
will no longer fail because this module now exists.
Take a look at mocha-webpack. As mentioned in the docs, it basically runs webpack test.js output.js && mocha output.js
with some optimizations. So, after npm i -D mocha-webpack
, your scripts
should look like:
"scripts": {
"test-mocha": "NODE_ENV=test node_modules/.bin/mocha-webpack --recursive test"
}
Another option you could try is to make use of mock-require, which is responsible for mocking node.js
modules. In your case you'll need to require mock-helper.js
:
"test-mocha": "NODE_ENV=test node_modules/.bin/mocha -r babel-register -r ./test/mock-helper.js --recursive test"
And ./test/mock-helper.js
should be something like:
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);
Hope it helps.
I would suggest you to use Karmajs
Karmajs is a test runner, so you can configure it to use mocha for running tests, also you can pre-process your tests with webpack, so all the pre-processing (for NormalModuleReplacementPlugin
and any other) which was done via webpack configuration is available when you're executing tests with Karma.
Basically, Install Karma and its associated Packages in your Application
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
Create 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,
},
});
};
Create tests.bundle.js
for running tests for all your test files, in this example, all our tests files have a file extension .spec.js
and are located inside ./src
directory.
tests.bundle.js
const context = require.context('./src', true, /\.spec\.js$/);
context.keys().forEach(context);
export default context;
For setting up Global variables which need to be available across all your app/tests can be set with karma.globals.js
file.
karma.globals.js
const __DEV__ = false;
const INITIAL_STATE = {
name: 'My App',
version: 'v2.5.6'
};
Once the above is configured, you can run all your tests from the directory where you have created karma.config.js and package.json by executing the following command.
yarn karma start
Note: Tests can be configured to execute in Headless Browsers (like phantomjs) as well, in this example we are using Chrome Browser to run our tests.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With