Karma-webpack: Unknown provider: LeaveServiceProvider <- LeaveService - angularjs

My app works like a charm but I can't run my tests with
$ yarn test
# node node_modules/karma/bin/karma start ./karma.conf.js --single-run
Version
"angular-mocks": "~1.5.10",
"karma-webpack": "^2.0.1",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2",
Error
PhantomJS 2.1.1 (Linux 0.0.0) leave API service create(): should create a leave FAILED
Error: [$injector:unpr] Unknown provider: LeaveServiceProvider <- LeaveService
http://errors.angularjs.org/1.5.10/$injector/unpr?p0=LeaveServiceProvider%20%3C-%20LeaveService (line 4674)
static/app.min.js:4674:87
getService#static/app.min.js:4827:40
static/app.min.js:4679:49
getService#static/app.min.js:4827:40
injectionArgs#static/app.min.js:4852:69
invoke#static/app.min.js:4874:32
WorkFn#node_modules/angular-mocks/angular-mocks.js:3130:26
inject#node_modules/angular-mocks/angular-mocks.js:3100:46
test/leave.service.tests.js:55:23
loaded#http://localhost:9876/context.js:151:17
inject#node_modules/angular-mocks/angular-mocks.js:3097:28
test/leave.service.tests.js:55:23
loaded#http://localhost:9876/context.js:151:17
TypeError: undefined is not an object (evaluating '$httpBackend.expectPOST') in test/leave.service.tests.js (line 64)
test/leave.service.tests.js:64:16
loaded#http://localhost:9876/context.js:151:17
TypeError: undefined is not an object (evaluating '$httpBackend.verifyNoOutstandingExpectation') in test/leave.service.tests.js (line 114)
test/leave.service.tests.js:114:16
loaded#http://localhost:9876/context.js:151:17
PhantomJS 2.1.1 (Linux 0.0.0): Executed 1 of 5 (1 FAILED) (skipped 4) ERROR (0.042 secs / 0.01 secs)
Karma.conf.js
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
module.exports = function (config) {
config.set({
basePath: './',
frameworks: ['jasmine', 'mocha', 'chai'],
files: [
'./static/app.min.js',
'node_modules/angular-mocks/angular-mocks.js',
{pattern: 'test/leave.service.tests.js'}
],
preprocessors: {
'test/leave.service.tests.js': ['webpack']
},
webpack: {
module: webpackConfig.module,
plugins: webpackConfig.plugins
},
webpackMiddleware: {
stats: 'errors-only'
},
notifyReporter: {
reportEachFailure: true,
reportSuccess: false
},
plugins: [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-webpack',
'karma-mocha',
'karma-chai'
],
browsers: ['PhantomJS']
});
};
webpack.conf.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
app: './src2/app.js'
},
output: {
path: path.resolve(__dirname, './static'),
publicPath: '/static/',
filename: 'app.min.js'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
moment: 'moment'
})
],
resolve: {
root: path.resolve('./src2'),
extensions: ['', '.js']
},
module: {
loaders: [
{test: /\.css$/, loader: 'style-loader!css-loader'},
{test: /\.scss$/, loader: 'style-loader!css-loader!sass-loader'},
{test: /\.html$/, loader: 'html-loader'},
{test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/font-woff'},
{test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/font-woff'},
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=application/octet-stream'},
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'},
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=8192&mimetype=image/svg+xml'}
]
},
devServer: {
port: 8080,
proxy: {
'/api': {
target: {
host: '0.0.0.0',
protocol: 'http:',
port: 8000
}
}
}
}
};
test/leave.service.js
var chai = require('chai');
var assert = chai.assert;
describe('leave API service', function () {
var service;
var $httpBackend;
beforeEach(inject(function (_$httpBackend_, LeaveService) {
$httpBackend = _$httpBackend_;
service = LeaveService;
}));
it('create(): should create a leave', function (done) {
var foo = 'bar';
assert.equal(foo, 'bar');
done();
});
});
Question
What's the matter here ?
related: Karma-webpack+angular TypeError: undefined is not an object (evaluating '$httpBackend.expectPOST'

When an Angular controller or a service depends on another Angular object (service, factory, constant...), the injector will look for it in the providers list (an array of singleton constructors). If there is no injector, or the dependency does not exist, angular will exit with an error like the one you have (no provider xProvider for service x). This should be resolved by mocking the angular module and attach depending services to it (method 1), or instantiate your LeaveService with a function returning an object filled with methods as its dependency argument, like
// leave-service.spec.js
...
var FakeHttpService = function() {
return {
get: function(url) { return new Promise(); },
post: function(url, data) { return new Promise(); },
//...
};
};
var leaveService = new LeaveService(new FakeHttpService());
Next, when you do something like var res = leaveService.get(url), it should call the FakeHttpService get method.
You should read the Angular Documentation on $httpBackend for further details about testing services that use the $http service (method 1), and understand how the injector works in a test environment.

I went back to a really simple test and add complexity step by step until it fails. The solution was to:
inject my app angular.mock.module('app')
beforeEach(angular.mock.module('app'));
inject the dependencies with angular.mock.inject()
beforeEach(function () {
angular.mock.inject(function (_$httpBackend_, _LeaveService_) {
$httpBackend = _$httpBackend_;
service = _LeaveService_;
});
});
load the built app, angular-mock and the test/**/*.js in karma.conf.js:
files: [
'./static/app.min.js',
'node_modules/angular-mocks/angular-mocks.js',
{pattern: 'test/foo.service.tests.js'}
]
Full code below
foo.service.tests.js
var chai = require('chai');
var assert = chai.assert;
describe('leave API service', function () {
var service;
var $httpBackend;
beforeEach(angular.mock.module('app'));
beforeEach(function () {
angular.mock.inject(function (_$httpBackend_, _LeaveService_) {
$httpBackend = _$httpBackend_;
service = _LeaveService_;
});
});
it('create(): should create a leave', function (done) {
var foo = 'bar';
assert.equal(foo, 'bar');
done();
});
});
webpack.conf.js
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
module.exports = {
entry: {
app: './src/app.js'
},
output: {
path: path.resolve(__dirname, './static'),
publicPath: '/static/',
filename: '[name]-[hash:8].min.js'
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
moment: 'moment',
Util: 'exports-loader?Util!bootstrap/js/dist/util'
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './src', 'index.html'),
filename: path.resolve(__dirname, 'index.html'),
alwaysWriteToDisk: true
}),
new HtmlWebpackHarddiskPlugin()
],
resolve: {alias: {Services: path.resolve(__dirname, 'src/services/')}},
module: {
rules: [
{test: /\.css$/, use: ['style-loader', 'css-loader']},
{test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader']},
{test: /\.html$/, use: ['html-loader']},
{test: /src.*\.js$/, use: ['ng-annotate-loader']},
{test: /\.(png|jpg|jpeg|gif|ico)$/, loader: 'file-loader?name=[name].[ext]'},
{test: /\.(woff|woff2|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}
]
},
devServer: {
port: 8080,
proxy: {
'/api': {target: 'http://0.0.0.0:8000'},
'/exports': {target: 'http://0.0.0.0:8000'},
'/media': {target: 'http://0.0.0.0:8000'}
}
}
};
Karma.con.js
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
module.exports = function (config) {
config.set({
basePath: './',
frameworks: ['jasmine', 'mocha', 'chai'],
files: [
'./static/app.min.js',
'node_modules/angular-mocks/angular-mocks.js',
{pattern: 'test/foo.service.tests.js'}
],
preprocessors: {
'test/foo.service.tests.js': ['webpack']
},
webpack: {
module: webpackConfig.module,
plugins: webpackConfig.plugins
},
webpackMiddleware: {
stats: 'errors-only'
},
notifyReporter: {
reportEachFailure: true,
reportSuccess: false
},
plugins: [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-webpack',
'karma-mocha',
'karma-chai'
],
browsers: ['PhantomJS']
});
};

Related

'Module is not available' when unit testing a component using typescript

Any ideas why the module is not found during the tests?
In karma.conf.js I've specified all the dependencies under the files property i.e angular, angular-mocks
But I have a feeling that app.component.ts and main.ts are not being compiled hence why they're not being found?
karma.conf.js
var webpackConfig = require('./webpack.test.config');
module.exports = function(config) {
'use strict';
var _config = {
basePath: '',
frameworks: ['jasmine', 'karma-typescript'],
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'src/app/app.component.ts',
'src/main.ts',
{
pattern: 'src/app/**/*.+(ts|html)'
}
],
preprocessors: {
'**/*.ts': ['karma-typescript']
},
webpack: webpackConfig,
karmaTypescriptConfig: {
bundlerOptions: {
entrypoints: /\.spec\.ts$/
},
compilerOptions: {
lib: ['ES2015', 'DOM']
}
},
reporters: ['progress', 'karma-typescript'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: true
};
config.set(_config);
};
webpack.test.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
devtool: 'inline-source-map',
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [{
test: /\.ts$/,
loaders: [{
loader: 'awesome-typescript-loader',
options: {
configFileName: path.join(__dirname, 'src', 'tsconfig.json')
}
}]
},
{
test: /\.html$/,
loader: 'html-loader'
}
]
}
};
app.component.spec.ts
import { AppComponent } from './app.component';
describe('Component: AppComponent', () => {
let Users;
beforeEach(function() {
angular.mock.module('myapp');
});
beforeEach(inject(function(_Users_: any) {
console.log(_Users_);
}));
});
app.component.ts
export class AppComponent implements ng.IComponentOptions {
static registeredName = 'dummy';
template: any;
constructor() {
this.template = require('./app.component.html');
}
}
main.ts
import { AppComponent } from "./app/app.component";
angular.module("myapp", ['pascalprecht.translate'])
.component(AppComponent.registeredName, new AppComponent())
.config(["$translateProvider", function($translateProvider: any) {
$translateProvider.determinePreferredLanguage();
}]);

Cannot Find Module Imported in Test File with Karma Webpack

I received an the following error:
Cannot find module "../controllers/loginCtrl" when running karma, controller file in src/controllers, test file in src/tests
1) karma.conf.js:
var path = require('path');
var hasCoverage = global.process.argv.reduce(function (result, arg) {
return arg.indexOf('coverage') !== -1 || result;
});
var include = [
path.resolve('./src')
];
var preLoaders = hasCoverage ? [
// Process test code with Babel
{test: /\.spec\.js$/, loader: 'babel', include: include},
// Process all non-test code with Isparta
{test: /\.js$/, loader: 'isparta', include: include, exclude: /\.spec\.js$/}
] : [
{test: /\.js$/, loader: 'babel', include: include}
];
var loaders = [
{test: /\.sass$/, loader: 'style!css?sourceMap!sass?sourceMap&indentedSyntax=true'},
{test: /\.png$/, loader: 'null'},
{test: /\.jpg$/, loader: 'null'},
// Loader for JSON, may be used in some tests
{test: /\.json$/, loader: 'json'},
// Need some real loaders for HTML, because angular directives are coupled with templates
{test: /\.haml$/, loader: 'hamlc-loader'},
{test: /\.html$/, loader: 'ng-cache?prefix=[dir]/[dir]'}
];
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
plugins: [
'karma-babel-preprocessor',
'karma-jasmine',
'karma-webpack',
'karma-phantomjs-launcher',
'karma-chrome-launcher',
],
files: [
'spec.js',
],
webpack: {
devtool: 'eval',
module: {
loaders: loaders,
preLoaders: preLoaders
},
cache: true
},
webpackMiddleware: {
stats: {
chunkModules: false,
colors: true
}
},
preprocessors: {
'spec.js': ['webpack'],
},
babelPreprocessor: {
options: {
presets: ['es2015'],
sourceMap: 'inline'
},
filename: function (file) {
return file.originalPath.replace(/\.js$/, '.es5.js');
},
sourceFileName: function (file) {
return file.originalPath;
}
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
singleRun: true
});
};
2) spec.js:
var testsContext;
require('babel-polyfill');
require('angular');
require('angular-mocks');
testsContext = require.context('./src/', true, /\.spec\.js$/);
testsContext.keys().forEach(testsContext);
3) LoginCtrl.spec.js:
import LoginCtrl from '../controllers/loginCtrl';
describe('controller: LoginCtrl', function() {
let scope;
let ctrl;
beforeEach(function() {
angular.module('envio', [])
.controller('LoginCtrl', LoginCtrl);
});
beforeEach(angular.mock.module('envio'));
beforeEach(angular.mock.inject(function($controller, $rootScope) {
scope = $rootScope.$new();
ctrl = $controller('LoginCtrl', {
$scope: scope
});
}));
it('should set message to null', function() {
expect(ctrl).toBeDefined();
// expect(scope.message).toBeNull();
});
});
How can I prevent this error?

TypeError: Cannot read property 'contextTypes' of undefined (karma+jasmine+reactRedux+webpack)

I am trying to execute jasmine test case of react+redux on webpack+karma background.
But getting below error
Below I have added webpack,karma config and react+redux component file.
1 ] karma.config.js
var webpackConfig = require('./webpack.config.js');
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'app/assets/test/**/*Spec.js',
'app/assets/test/**/*Spec.jsx'
],
preprocessors: {
'app/assets/test/**/*Spec.js': ['webpack'],
'app/assets/test/**/*Spec.jsx': ['webpack']
},
webpack: webpackConfig,
reporters: ['kjhtml'],
port: 9876,
colors: true,
config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: true,
concurrency: Infinity
})
}
2 ] react home.jsx component
import CarouselContainer from 'containers/carouselContainer'
import CurrentTracks from 'containers/currentTracks'
export default class Home extends React.Component {
render() {
return (
<div>
<CarouselContainer />
<CurrentTracks />
</div>
)
}
}
3 ] home.Spec.jsx -
import React from 'react';
import { shallow } from 'enzyme';
import ReactTestUtils from 'react-addons-test-utils'
import {Home} from 'pages/home'
describe("User suite", function() {
const wrapper = shallow(<Home/>);
expect(wrapper.length).toEqual(1);
});
4 ] Webpack.config.js -
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var autoprefixer = require('autoprefixer');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var merge = require('webpack-merge');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var BUILD = path.join(__dirname, 'build');
var APP = path.join(__dirname, 'app');
var JS = path.join(APP, 'assets', 'javascript');
var env = process.env.NODE_ENV;
console.log('Webpack env: ' + env)
var sassLoaders = [
'css-loader',
'postcss-loader',
'sass-loader?indentedSyntax=sass&includePaths[]=' + APP
];
var commonConfig = {
entry: [ path.join(JS, 'index.jsx') ],
module: {
loaders: [
{ test: /\.jsx?$/, exclude: /node_modules/, loaders: ['babel-loader'] },
{ test: /\.css/, loader: 'style-loader!css-loader?name=assets/css/[name]-[hash].[ext]' },
{ test: /\.png|jpg|gif$/, loader: 'file-loader?name=assets/images/[name]-[hash].[ext]' },
{ test: /\.xlsx$/, loader: 'file-loader?name=assets/file/[name].[ext]' },
{ test: /\.sass$/, loader: ExtractTextPlugin.extract('style-loader', sassLoaders.join('!')) },
{ test: /\.(woff|woff2|svg|ttf|eot|ico)$/, loader: 'file-loader?name=assets/fonts/[name].[ext]' }
]
},
output: {
filename: 'assets/javascript/[name]-[hash].js',
path: BUILD,
publicPath: '/'
},
externals: {
'jsdom': 'window',
'cheerio': 'window',
'react/lib/ExecutionEnvironment': true,
'react/addons': true,
'react/lib/ReactContext': 'window'
},
plugins: [
new HtmlWebpackPlugin({
template: 'app/index.html',
inject: 'body',
filename: 'index.html',
favicon: path.join(APP, 'assets', 'images', 'favicon.ico')
}),
new ExtractTextPlugin('assets/stylesheet/[name]-[hash].min.css'),
new CopyWebpackPlugin([
{ from: path.join(APP,'assets/javascript/vendor'), to: 'assets/vendor' }
]),
new CopyWebpackPlugin([
{ from: path.join(APP,'assets/test'), to: 'assets/test' }
]),
new webpack.ProvidePlugin({
React: "react",
"_": "lodash"
})
],
postcss: [
autoprefixer({
browsers: ['last 2 versions']
})
],
resolve: {
root: path.join(APP, 'assets'),
alias: {
config: '../../../../configs',
images: 'images',
actions: 'javascript/actions',
containers: 'javascript/containers',
components: 'javascript/components',
common: 'components/common',
constants: 'javascript/constants',
javascript: 'javascript',
layout: 'components/layout',
mywagers: 'pages/myWagers',
pages: 'components/pages',
home: 'pages/home',
utility: 'javascript/utility',
wagers: 'pages/wagers',
sheets: 'wagers/betPad/sheets'
},
extensions: ['', '.js', '.jsx', '.sass'],
modulesDirectories: ['app', 'node_modules']
}
};
var devConfig = {
devtool: 'inline-source-map',
entry: ['webpack-hot-middleware/client?reload=true'],
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env || 'development')
})
],
module: {
postLoaders: [
{
test: /\.js$/,
exclude: [/node_modules/,/vendor/],
loader: "jshint-loader"
}
]
}
};
var prodConfig = {
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env || 'production')
})
]
};
var config;
switch (env) {
case 'development':
config = merge(devConfig, commonConfig);
break;
default:
config = merge(prodConfig, commonConfig);
break;
}
module.exports = config;
It looks like Home is a default export, so in your spec on line 4, you should be importing as a default.
So the line should look like
import Home from 'pages/home';
instead of
import {Home} from 'pages/home';

only one install of babel polyfill is allowed when running karma/enzyme test

When I run karma test with enzyme I get an error:
only one instance of babel-polyfill is allowed at ...
The is the test file that caused this error:
import React from 'react';
import { Provider } from 'react-redux';
import configureStore from '../../src/common/store/configureStore';
import { shallow,mount } from 'enzyme';
import ChatContainer from '../../src/common/containers/ChatContainer';
const initialState = window.__INITIAL_STATE__;
const store = configureStore(initialState);
describe('ChatContainer Component', () => {
let Component;
beforeEach(() => {
Component =
mount(<Provider store={store}>
<ChatContainer />
</Provider>);
});
it('should render', () => {
expect(Component).toBeTruthy();
});
});
This is the only file so far that is triggering this error so I dont know why..
I am not sure if it is the babel-plugin-transform-class-properties in my karma config that is causing this issue:
/* eslint-disable no-var */
var path = require('path');
module.exports = function webpackConfig(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'test/components/*.spec.js',
// 'test/test_index.js',
],
preprocessors: {
'src/js/**/*.js': ['webpack', 'sourcemap'],
'test/**/*.spec.js': ['webpack', 'sourcemap'],
// 'test/test_index.js': ['webpack', 'sourcemap'],
},
webpack: {
devtool: 'inline-source-map',
alias: {
cheerio: 'cheerio/lib/cheerio',
},
module: {
loaders: [{
test: /\.js$/,
loader: 'babel',
query: {
presets: ['airbnb'],
plugins: ["transform-class-properties"]
},
exclude: path.resolve(__dirname, 'node_modules'),
}, {
test: /\.json$/,
loader: 'json',
},
],
},
externals: {
cherrio: 'window',
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': 'window',
'react/addons': true,
},
},
webpackServer: {
noInfo: true,
},
plugins: [
'karma-webpack',
'karma-jasmine',
'karma-sourcemap-loader',
'karma-phantomjs-launcher',
'karma-spec-reporter',
'karma-chrome-launcher',
],
babelPreprocessor: {
options: {
presets: ['airbnb'],
},
},
reporters: ['spec'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
singleRun: false,
});
};
Here is my webpack config:
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'inline-source-map',
entry: [
'babel-polyfill',
'webpack-hot-middleware/client',
'./src/client/index'
],
output: {
path: path.resolve(__dirname, './static/dist'),
filename: 'bundle.js',
publicPath: '/dist/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')
}
})
],
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
query: {
plugins: [,
[
'react-transform', {
transforms: [{
transform: ['react-transform-hmr']
imports: ['react'],
locals: ['module']
}, {
transform: 'react-transform-catch-errors',
imports: ['react', 'redbox-react']
}]
}
]
]
},
include: [path.resolve(__dirname, 'src')]
},
{
test: /\.css?$/,
loaders: ['style', 'raw']
}
]
}
};

Webpack error while loading module DomUtils after import enzyme

I have a project with TypeScript and React 0.14.
And I set-up test enviroment with karma/mocha/chai. And its work. But when I import and use function from enzyme I got error in browser (Human-readable error from Chrome):
Uncaught TypeError: ext[key].bind is not a function
As I understood modules 227...232 (internal DomUtils files) not loaded before using.
Maybe I forgot something? Or does anyone know workaround?
Sorry for huge configs:
Webpack config:
var webpack = require("webpack"),
path = require("path"),
ExtractTextPlugin = require("extract-text-webpack-plugin"),
precss = require('precss'),
autoprefixer = require('autoprefixer');
module.exports = {
entry: [
path.resolve(__dirname, "app/app.tsx")
],
output: {
filename: "bundle.js",
publicPath: "/build/",
path: path.resolve(__dirname, "build")
},
module: {
loaders: [
{test: /\.json$/, loader: 'json'},
{test: /\.tsx$/, exclude: /node_modules/, loader: 'es3ify!ts'},
{test: /\.s?css$/, loader: ExtractTextPlugin.extract('style', 'css!postcss')},
{test: /\.svg|eot|ttf|woff|woff2|ico|png|gif|jpg($|\?)/, loader: 'file'}
]
},
postcss: function () {
return [precss, autoprefixer];
},
resolve: {
root: path.resolve(__dirname, "app"),
extensions: ["", ".js", ".ts", ".tsx", ".json"]
},
plugins: [
new ExtractTextPlugin("bundle.css")
]
};
Karma config:
var webpack = require('webpack');
var webpackConfig = require('./webpack.config');
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['mocha', 'chai', 'sinon'],
files: [
'app/**/*-test.tsx'
],
exclude: [],
preprocessors: {
'app/**/*.tsx': ['webpack']
},
webpack: {
resolve: webpackConfig.resolve,
module: webpackConfig.module,
externals: {
'cheereo': 'window',
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
}
},
reporters: ['progress', 'spec'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
singleRun: true,
concurrency: Infinity
})
}
Test file:
import * as React from 'react';
import { shallow } from 'enzyme';
describe('Dashboard', () => {
it('should be OK', () => {
const instance = shallow(<div />);
expect(true).to.equal(true, 'true === true');
});
});
Webpack import chain: enzyme -> ... -> cheerio -> ... -> DomUtils
StackOverflow my last chance to solve the problem, Google don't know answer.
I've faced with same issue, for me it helps to put domutils as extrenal in webpack configuration. Based on your config try this:
webpack: {
resolve: webpackConfig.resolve,
module: webpackConfig.module,
externals: {
'domutils': 'true',
'cheereo': 'window',
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
}
}

Resources