设置 webpack karma 和 angular-mocks
Setting up webpack karma and angular-mocks
我在设置我的 webpack 时遇到了这个问题。我正在现有项目上设置 webpack,另外我正在引入 ES6。我想以 'correct' 的方式进行测试,在一些大的 change.That 之后通过测试,这就是我需要设置业力测试的原因。
该应用程序正在使用 AngularJS 1,并且我正在使用 Angular-Mocks(使用 Jasmina 和 PhantomJS 进行业力设置)进行测试。
我抛出了很多现有的解决方案,如何使用 karama 和 angular 设置 webpack,但是没有一个例子让我的测试工作。基本上问题在于注入和模拟。
例如,我在尝试注入 $rootScope 或 $backendMock 时变得不确定。
这是我当前的设置:
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const rootPath = path.resolve(__dirname, "src");
const libsDir = rootPath + "/lib";
const applicationDir = libsDir + "/app";
const plugins =
[
new CleanWebpackPlugin('build', {
root: rootPath,
verbose: true,
dry: false
}),
new webpack.EnvironmentPlugin({
PROD_ENV: false
}),
new HtmlWebpackPlugin({
template: 'src/index.tmpl.ejs',
inject: 'head',
filename: 'index.html'
}),
new ExtractTextPlugin('style/[name].css'),
new webpack.ProvidePlugin({
$: "jquery",
jquery: "jquery",
"window.jQuery": "jquery",
jQuery: "jquery"
})
];
module.exports = {
devtool: 'source-map',
entry: {
vendors: libsDir + "/components.js",
application: applicationDir + "/Application.js",
browserDetect: applicationDir + "/BrowserDetection.js"
},
output: {
path: __dirname + "/build",
publicPath: '',
filename: "[name].bundle.js",
sourceMapFilename: "[name].bundle.map",
chunkFilename: '[chunkhash].js'
},
module: {
loaders: [
{
test: /\.html$/,
loader: "ngtemplate-loader!html-loader"
}, {
test: /\.(svg|png|jpe?g|ttf|woff2?|eot)$/,
loader: 'url-loader?limit=10000&name=style/[name].[ext]'
}, {
test: /\.(scss|css)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader?minimize', 'resolve-url-loader', 'sass-loader?sourceMap']
})
}
]
},
plugins: plugins,
node: {
net: 'empty',
tls: 'empty',
//dns: 'empty',
fs: 'empty'
}
};
karma.config.js
var webpackConfig = require('./webpack.config');
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
{pattern: 'tests/karma.entry.js'}
],
// list of files to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'tests/karma.entry.js' : ['webpack']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: "errors-only"
},
ngHtml2JsPreprocessor: {
// setting this option will create only a single module that contains templates
// from all the files, so you can load them all with module('foo')
moduleName: 'templates',
stripPrefix: 'src/'
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
//TEST
// reporters: ['progress', 'html', 'junit', 'coverage'],
//TEST
// coverageReporter: {
// dir: 'reports',
// reporters: [
// {type: 'cobertura', subdir: 'xml', file: 'code-coverage.xml'},
// {type: 'html', subdir: 'html'}
// ]
// },
// the default configuration
htmlReporter: {
outputFile: 'reports/html/ui-unit-tests.html'
},
junitReporter: {
outputFile: 'reports/xml/ui-unit-tests.xml'
},
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_DEBUG,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true ,
plugins: [
require('karma-webpack'),
require('karma-jasmine'),
require('karma-coverage'),
require('karma-phantomjs-launcher'),
require('karma-chrome-launcher'),
].
});
};
karma.entry.js
var testsContext = require.context(".", true, /\.spec\.js/);
testsContext.keys().forEach(testsContext);
没有我所有的测试都在一个单独的文件中 -> /tests/**/*.spec.js,这些被拾取并且 PhanthomJS 正在尝试 运行 它们。
这是我的一项测试运行:
describe('contextmenu', function () {
var customersEndpoint = '/api/v1/res/customers',
directiveScope,
$httpBackendMock,
contextMenuDomElement,
compileDirective,
contextService,
contextsReturnedFromBackend = [
{name: "Kjell's Buildings and Stuffz", id: 1},
{name: "IMA Stats Runners", id: 2},
{name: "Juice and Gin Inc.", id: 3}
];
beforeEach(angular.mock.module("FES"));
beforeEach(angular.mock.module("templates"));
beforeEach(function () {
angular.mock.inject(function (_$rootScope_, _$compile_, _$httpBackend_, _ContextService_) {
contextService = _ContextService_;
$httpBackendMock = _$httpBackend_;
$httpBackendMock.when('GET', customersEndpoint)
.respond(contextsReturnedFromBackend);
compileDirective = function() {
directiveScope = _$rootScope_.$new();
contextMenuDomElement = _$compile_(angular.element("<contextmenu></contextmenu>"))(directiveScope);
directiveScope.$digest();
};
});
});
describe('on init', function() {
it('calls the context service to get available contexts and select first item', function() {
$httpBackendMock.expectGET(customersEndpoint);
compileDirective();
$httpBackendMock.flush(); // this returns the $http request that was made on init in the controller
directiveScope.$digest();
console.log(directiveScope);
expect(directiveScope.contexts.length).toBe(3);
expect(contextMenuDomElement.html()).toContain(contextsReturnedFromBackend[0].name);
})
});
describe('on context clicked', function() {
it('sets the current context', function() {
var newContextToSelect = directiveScope.contexts[1];
directiveScope.onContextClicked(newContextToSelect);
expect(directiveScope.selectedContext).toBe(newContextToSelect);
});
});
});
我收到的错误是 $httpBackendMock 或 directiveScope 未定义。
PhantomJS 2.1.1 (Linux 0.0.0) contextmenu on init calls the context service to get available contexts and select first item FAILED
forEach@node_modules/angular/angular.js:402:24
loadModules@node_modules/angular/angular.js:4880:12
createInjector@node_modules/angular/angular.js:4802:30
WorkFn@node_modules/angular-mocks/angular-mocks.js:3161:60
inject@node_modules/angular-mocks/angular-mocks.js:3141:46
tests/karma.entry.js:165:28
loaded@http://localhost:9876/context.js:151:17
node_modules/angular/angular.js:4921:53
TypeError: undefined is not an object (evaluating '$httpBackendMock.expectGET') in tests/karma.entry.js (line 182)
tests/karma.entry.js:182:28
loaded@http://localhost:9876/context.js:151:17
PhantomJS 2.1.1 (Linux 0.0.0) contextmenu on context clicked sets the current context FAILED
forEach@node_modules/angular/angular.js:402:24
loadModules@node_modules/angular/angular.js:4880:12
createInjector@node_modules/angular/angular.js:4802:30
WorkFn@node_modules/angular-mocks/angular-mocks.js:3161:60
inject@node_modules/angular-mocks/angular-mocks.js:3141:46
tests/karma.entry.js:165:28
loaded@http://localhost:9876/context.js:151:17
node_modules/angular/angular.js:4921:53
TypeError: undefined is not an object (evaluating 'directiveScope.contexts') in tests/karma.entry.js (line 194)
tests/karma.entry.js:194:52
loaded@http://localhost:9876/context.js:151:17
我正在 运行ning Angular 1.6.2、Webpack 2.2.1、Karma-Webpack 2.0.2 和 1.5.0 版的 Karma。
我试图在 ES6 中编写我的模块并在 webpack 中转换它。
你们能帮忙吗?我已经坚持了很长时间;/我知道有新的 'better' 解决方案来测试 ES6 模块,但我需要
你们能帮帮我吗?
当 AngularJS 找不到所需的提供商时,此设置有时会非常糟糕。它没有抛出错误,而是退出,不输入任何 inject
函数并启动 it
块。因此,您通常从 $injector
中获得的值仍然未定义。
看看您是否真的模拟了所有必需的依赖项,通过 angular.mock.module('serviceModule')
包含它们的模块,或者通过创建和配置间谍对象。
angular.mock.module(($provider: ng.auto.IProvideService) => {
$provider.value('service', jasmine.createSpyObj('service', ['list of accessed modules']);
});
我在设置我的 webpack 时遇到了这个问题。我正在现有项目上设置 webpack,另外我正在引入 ES6。我想以 'correct' 的方式进行测试,在一些大的 change.That 之后通过测试,这就是我需要设置业力测试的原因。 该应用程序正在使用 AngularJS 1,并且我正在使用 Angular-Mocks(使用 Jasmina 和 PhantomJS 进行业力设置)进行测试。
我抛出了很多现有的解决方案,如何使用 karama 和 angular 设置 webpack,但是没有一个例子让我的测试工作。基本上问题在于注入和模拟。 例如,我在尝试注入 $rootScope 或 $backendMock 时变得不确定。
这是我当前的设置:
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const rootPath = path.resolve(__dirname, "src");
const libsDir = rootPath + "/lib";
const applicationDir = libsDir + "/app";
const plugins =
[
new CleanWebpackPlugin('build', {
root: rootPath,
verbose: true,
dry: false
}),
new webpack.EnvironmentPlugin({
PROD_ENV: false
}),
new HtmlWebpackPlugin({
template: 'src/index.tmpl.ejs',
inject: 'head',
filename: 'index.html'
}),
new ExtractTextPlugin('style/[name].css'),
new webpack.ProvidePlugin({
$: "jquery",
jquery: "jquery",
"window.jQuery": "jquery",
jQuery: "jquery"
})
];
module.exports = {
devtool: 'source-map',
entry: {
vendors: libsDir + "/components.js",
application: applicationDir + "/Application.js",
browserDetect: applicationDir + "/BrowserDetection.js"
},
output: {
path: __dirname + "/build",
publicPath: '',
filename: "[name].bundle.js",
sourceMapFilename: "[name].bundle.map",
chunkFilename: '[chunkhash].js'
},
module: {
loaders: [
{
test: /\.html$/,
loader: "ngtemplate-loader!html-loader"
}, {
test: /\.(svg|png|jpe?g|ttf|woff2?|eot)$/,
loader: 'url-loader?limit=10000&name=style/[name].[ext]'
}, {
test: /\.(scss|css)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader?minimize', 'resolve-url-loader', 'sass-loader?sourceMap']
})
}
]
},
plugins: plugins,
node: {
net: 'empty',
tls: 'empty',
//dns: 'empty',
fs: 'empty'
}
};
karma.config.js
var webpackConfig = require('./webpack.config');
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
{pattern: 'tests/karma.entry.js'}
],
// list of files to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'tests/karma.entry.js' : ['webpack']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: "errors-only"
},
ngHtml2JsPreprocessor: {
// setting this option will create only a single module that contains templates
// from all the files, so you can load them all with module('foo')
moduleName: 'templates',
stripPrefix: 'src/'
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
//TEST
// reporters: ['progress', 'html', 'junit', 'coverage'],
//TEST
// coverageReporter: {
// dir: 'reports',
// reporters: [
// {type: 'cobertura', subdir: 'xml', file: 'code-coverage.xml'},
// {type: 'html', subdir: 'html'}
// ]
// },
// the default configuration
htmlReporter: {
outputFile: 'reports/html/ui-unit-tests.html'
},
junitReporter: {
outputFile: 'reports/xml/ui-unit-tests.xml'
},
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_DEBUG,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true ,
plugins: [
require('karma-webpack'),
require('karma-jasmine'),
require('karma-coverage'),
require('karma-phantomjs-launcher'),
require('karma-chrome-launcher'),
].
});
};
karma.entry.js
var testsContext = require.context(".", true, /\.spec\.js/);
testsContext.keys().forEach(testsContext);
没有我所有的测试都在一个单独的文件中 -> /tests/**/*.spec.js,这些被拾取并且 PhanthomJS 正在尝试 运行 它们。
这是我的一项测试运行:
describe('contextmenu', function () {
var customersEndpoint = '/api/v1/res/customers',
directiveScope,
$httpBackendMock,
contextMenuDomElement,
compileDirective,
contextService,
contextsReturnedFromBackend = [
{name: "Kjell's Buildings and Stuffz", id: 1},
{name: "IMA Stats Runners", id: 2},
{name: "Juice and Gin Inc.", id: 3}
];
beforeEach(angular.mock.module("FES"));
beforeEach(angular.mock.module("templates"));
beforeEach(function () {
angular.mock.inject(function (_$rootScope_, _$compile_, _$httpBackend_, _ContextService_) {
contextService = _ContextService_;
$httpBackendMock = _$httpBackend_;
$httpBackendMock.when('GET', customersEndpoint)
.respond(contextsReturnedFromBackend);
compileDirective = function() {
directiveScope = _$rootScope_.$new();
contextMenuDomElement = _$compile_(angular.element("<contextmenu></contextmenu>"))(directiveScope);
directiveScope.$digest();
};
});
});
describe('on init', function() {
it('calls the context service to get available contexts and select first item', function() {
$httpBackendMock.expectGET(customersEndpoint);
compileDirective();
$httpBackendMock.flush(); // this returns the $http request that was made on init in the controller
directiveScope.$digest();
console.log(directiveScope);
expect(directiveScope.contexts.length).toBe(3);
expect(contextMenuDomElement.html()).toContain(contextsReturnedFromBackend[0].name);
})
});
describe('on context clicked', function() {
it('sets the current context', function() {
var newContextToSelect = directiveScope.contexts[1];
directiveScope.onContextClicked(newContextToSelect);
expect(directiveScope.selectedContext).toBe(newContextToSelect);
});
});
});
我收到的错误是 $httpBackendMock 或 directiveScope 未定义。
PhantomJS 2.1.1 (Linux 0.0.0) contextmenu on init calls the context service to get available contexts and select first item FAILED
forEach@node_modules/angular/angular.js:402:24
loadModules@node_modules/angular/angular.js:4880:12
createInjector@node_modules/angular/angular.js:4802:30
WorkFn@node_modules/angular-mocks/angular-mocks.js:3161:60
inject@node_modules/angular-mocks/angular-mocks.js:3141:46
tests/karma.entry.js:165:28
loaded@http://localhost:9876/context.js:151:17
node_modules/angular/angular.js:4921:53
TypeError: undefined is not an object (evaluating '$httpBackendMock.expectGET') in tests/karma.entry.js (line 182)
tests/karma.entry.js:182:28
loaded@http://localhost:9876/context.js:151:17
PhantomJS 2.1.1 (Linux 0.0.0) contextmenu on context clicked sets the current context FAILED
forEach@node_modules/angular/angular.js:402:24
loadModules@node_modules/angular/angular.js:4880:12
createInjector@node_modules/angular/angular.js:4802:30
WorkFn@node_modules/angular-mocks/angular-mocks.js:3161:60
inject@node_modules/angular-mocks/angular-mocks.js:3141:46
tests/karma.entry.js:165:28
loaded@http://localhost:9876/context.js:151:17
node_modules/angular/angular.js:4921:53
TypeError: undefined is not an object (evaluating 'directiveScope.contexts') in tests/karma.entry.js (line 194)
tests/karma.entry.js:194:52
loaded@http://localhost:9876/context.js:151:17
我正在 运行ning Angular 1.6.2、Webpack 2.2.1、Karma-Webpack 2.0.2 和 1.5.0 版的 Karma。 我试图在 ES6 中编写我的模块并在 webpack 中转换它。 你们能帮忙吗?我已经坚持了很长时间;/我知道有新的 'better' 解决方案来测试 ES6 模块,但我需要
你们能帮帮我吗?
当 AngularJS 找不到所需的提供商时,此设置有时会非常糟糕。它没有抛出错误,而是退出,不输入任何 inject
函数并启动 it
块。因此,您通常从 $injector
中获得的值仍然未定义。
看看您是否真的模拟了所有必需的依赖项,通过 angular.mock.module('serviceModule')
包含它们的模块,或者通过创建和配置间谍对象。
angular.mock.module(($provider: ng.auto.IProvideService) => {
$provider.value('service', jasmine.createSpyObj('service', ['list of accessed modules']);
});