我正在尝试使用 Karma 来测试我的 React JS 应用程序。但是,它会出现各种错误,因为它正在尝试加载/启动完整的应用程序。我的第一个错误是
不变违规:_registerComponent(...):目标容器不是 DOM 元素,它出现在我的 entry.js 中,在 webpack 中作为入口点列出,但我在我的 karma.conf.js 中删除了它。
我在 entry.js 中通过添加 dom 元素来解决它,以防它不存在。然后我试图在一些未定义的历史对象上调用方法“getCurrentLocation()”,它出现在一些不是我的模块中:(
底线:为什么在我的 utils.js 中测试一个方法时,业力会加载/启动我的完整应用程序。我的 test.js 目前看起来像:
let Utils = require('../utils');
我评论了其余部分以隔离错误。下面列出了我的 karma.conf.js 和 webpack.config.js: karma.conf.js:
let webpackConfig = require('./webpack.config');
webpackConfig.entry = {};
module.exports = function (config) {
config.set({
basePath: 'src/js/',
frameworks: ['jasmine-jquery', 'jasmine'],
files: [
"**/tests/*.test.js",
],
preprocessors: {
"**/tests/*.test.js": ['webpack', 'sourcemap'],
},
webpack: webpackConfig(),
webpackMiddleware: {
stats: "errors-only"
},
reporters: ['mocha'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
phantomJsLauncher: {
exitOnResourceError: true
},
singleRun: false,
concurrency: Infinity
})
};
--- webpack.config.js:
"use strict";
const webpack = require('webpack');
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
let mode = process.env.WEBPACK_ENV;
let isProdBuild = mode === 'prod';
let isAcceptBuild = mode === 'accept';
let isTestBuild = mode === 'test';
let isTestRun = mode === 'testRun';
let isDev = mode === 'dev';
console.log("Mode: " + mode)
let devServer = {};
let devTool = 'source-map';
let plugins = [];
/* plugins.push(new CopyWebpackPlugin([
{from: 'src/js/vendor.js', to: 'src/js/vendor.js'},
])); */
// Used to inject the entry.js.
plugins.push(new HtmlWebpackPlugin({
template: 'index.tpl',
inject: 'body',
}));
plugins.push(new CleanWebpackPlugin(['dist/*'], {verbose: true}));
if (isProdBuild || isAcceptBuild) {
plugins.push(new webpack.optimize.UglifyJsPlugin({minimize: true, sourceMap: true}));
plugins.push(new webpack.optimize.AggressiveMergingPlugin());
plugins.push(new webpack.DefinePlugin({'process.env': {'NODE_ENV': JSON.stringify('production')}}));
let CompressionPlugin = require("compression-webpack-plugin");
plugins.push(new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
}));
}
else if (isDev) {
devServer = {inline: true, port: 3000};
devTool = 'inline-source-map';
}
if (!isTestRun) {
plugins.push(new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks(module, count) {
let context = module.context;
return context && context.indexOf('node_modules') >= 0;
},
}));
plugins.push(new webpack.optimize.CommonsChunkPlugin({name: 'manifest'}));
}
module.exports = function (env) {
return {
entry: {
entry: ['./src/entry.js', './src/js/utils.js'],
},
devtool: devTool,
devServer: devServer,
output: {
path: __dirname + '/dist',
filename: '[name]-[hash].cache.js',
sourceMapFilename: '[name]-[hash].cache.js.map',
},
module: {
rules: [
{ // The Babel loader:
test: /(\.jsx|\.js)$/,
exclude: /(node_modules|bower_components)/,
use: [{
loader: 'babel-loader',
options: {
presets: ['babel-preset-es2015', 'babel-preset-react'].map(require.resolve),
plugins: ['babel-plugin-transform-react-jsx-img-import'].map(require.resolve)
}
}]
},
{
test: /\.s?css$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|gif|jpe?g)$/,
use: [{
loader: 'file-loader',
options: {
name: 'resources/images/[name]-[hash]-cache.[ext]'
}
}]
},
{
test: /\.(otf|svg|eot|ttf|woff2?)(\?.*$|$)/,
use: [{
loader: 'file-loader',
options: {
name: 'resources/fonts/[name]-[hash]-cache.[ext]'
}
}]
},
]
},
plugins: plugins,
};
};