Angular 1.5 Karma单元测试加载ng-mock两次
Angular 1.5 Karma unit test loads ng-mock twice
我有一个用 Typescript 2.4.2 编写的网络应用程序,由最新的 Webpack 版本 (2.7.0) 编译。
我正在使用 Jasmine 作为断言库添加 Karma 测试。
这是我的业力配置文件:
'use strict';
const webpack = require('./webpack.config');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const _ = require('lodash');
_.remove(webpack.plugins, plugin => plugin instanceof CleanWebpackPlugin);
webpack.module.rules.forEach(rule => {
if (rule.loader === 'ts-loader') {
rule.exclude = /sg\.d\.ts/;
}
});
module.exports = function (config) {
config.set({
webpack,
mime: {
'text/x-typescript': ['ts','tsx']
},
// 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: [
{ pattern: 'app/scripts/**/*.test.ts', watched: true}
],
preprocessors: {
"app/scripts/**/*.test.ts": ["webpack"]
},
// list of files to exclude
exclude: [],
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'mocha'],
// 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_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['jsdom', /*'Chrome'*/],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
在第一个测试套件中我没有遇到任何问题,它看起来像这样:
import { default as moduleName } from "../module";
import { ListService, IListRequest } from "./listService";
import * as angular from 'angular';
import "angular-mocks";
import "jasmine";
const { module, inject } = angular.mock;
describe("List service", () => {
let serviceToTest: ListService;
let rootScope: ng.IRootScopeService;
let httpBackend: ng.IHttpBackendService;
beforeEach(module(moduleName));
beforeEach(() => {
inject(['$rootScope', '$httpBackend', ListService.SERVICE_NAME,
($rootScope: ng.IRootScopeService, $httpBackend: ng.IHttpBackendService, listService: ListService) => {
serviceToTest = listService;
rootScope = $rootScope;
httpBackend = $httpBackend;
}]);
});
it("service should not be null", () => {
expect(serviceToTest).toBeDefined();
});
// Other tests
});
当我尝试为另一个服务编写测试套件时出现问题:
import { default as moduleName } from "../module";
import { RedirectionService } from "./RedirectionService";
import * as angular from 'angular';
import "angular-mocks";
import "jasmine";
const { module, inject } = angular.mock;
describe('Redirection service', () => {
});
如您所见,第二个测试套件是空的。
我的问题是,一旦我添加了第二个套件,Angular 就开始抛出错误 - 它会尝试加载 Angular 和 ng-mock 两次,每个导入它们的新文件一次。
抛出的错误是:
Error: [$injector:modulerr] Failed to instantiate module ngLocale due
to:
RangeError: Maximum call stack size exceeded
快速 Google 搜索产生了很多关于这个问题的线程 - 说当 Karma 加载 ng-mock 两次时会弹出这个错误。
此外,调试 Chrome 上的代码确认是 ngMock 未能初始化,并且 Angular 产生警告 Angular 被加载两次。
我该怎么办?
在我看来,业力似乎分开对待每个测试文件,所以它不使用 Webpack 将 Angular 捆绑到一个模块中,而是单独编译每个文件并添加 Angular 和 ng-mock再次。
我走了一条不同的路,想不出如何解决这个问题。
我的 webpack 配置现在有这个:
entry: { entry: './app/scripts/main.ts'},
output: {
filename: isDev ? "[name].js" : '[name]-[hash].js',
path: path.resolve('dist'),
pathinfo: isDev
},
...
if (isDev) {
module.exports.devtool = 'source-map';
module.exports.entry.test = './test/test-main.ts';
}
而且我在 Karma 配置中删除了所有 webpack 的东西。
我告诉 Webpack 编译另一个包,带有一个简单的入口点 TS 文件,内容如下:
Import((<any>require).context('../app/scripts/', true, /.*\.test\.ts$/i), (_: any) => {});
Karma 正在观察输出包文件的变化。
我通过添加包含所有使用 angular-mock 的测试的 angular-services.test.ts
文件解决了这个问题。例如,他们在每个内部使用 angular.mock.module
和 inject
方法。
angular-services.test.ts内容:
import 'angular';
import 'angular-mocks';
import 'test_angular_service_1.test'
import 'test_angular_service_2.test'
.
.
import 'test_angular_service_n.test'
我有一个用 Typescript 2.4.2 编写的网络应用程序,由最新的 Webpack 版本 (2.7.0) 编译。
我正在使用 Jasmine 作为断言库添加 Karma 测试。
这是我的业力配置文件:
'use strict';
const webpack = require('./webpack.config');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const _ = require('lodash');
_.remove(webpack.plugins, plugin => plugin instanceof CleanWebpackPlugin);
webpack.module.rules.forEach(rule => {
if (rule.loader === 'ts-loader') {
rule.exclude = /sg\.d\.ts/;
}
});
module.exports = function (config) {
config.set({
webpack,
mime: {
'text/x-typescript': ['ts','tsx']
},
// 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: [
{ pattern: 'app/scripts/**/*.test.ts', watched: true}
],
preprocessors: {
"app/scripts/**/*.test.ts": ["webpack"]
},
// list of files to exclude
exclude: [],
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'mocha'],
// 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_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['jsdom', /*'Chrome'*/],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
在第一个测试套件中我没有遇到任何问题,它看起来像这样:
import { default as moduleName } from "../module";
import { ListService, IListRequest } from "./listService";
import * as angular from 'angular';
import "angular-mocks";
import "jasmine";
const { module, inject } = angular.mock;
describe("List service", () => {
let serviceToTest: ListService;
let rootScope: ng.IRootScopeService;
let httpBackend: ng.IHttpBackendService;
beforeEach(module(moduleName));
beforeEach(() => {
inject(['$rootScope', '$httpBackend', ListService.SERVICE_NAME,
($rootScope: ng.IRootScopeService, $httpBackend: ng.IHttpBackendService, listService: ListService) => {
serviceToTest = listService;
rootScope = $rootScope;
httpBackend = $httpBackend;
}]);
});
it("service should not be null", () => {
expect(serviceToTest).toBeDefined();
});
// Other tests
});
当我尝试为另一个服务编写测试套件时出现问题:
import { default as moduleName } from "../module";
import { RedirectionService } from "./RedirectionService";
import * as angular from 'angular';
import "angular-mocks";
import "jasmine";
const { module, inject } = angular.mock;
describe('Redirection service', () => {
});
如您所见,第二个测试套件是空的。
我的问题是,一旦我添加了第二个套件,Angular 就开始抛出错误 - 它会尝试加载 Angular 和 ng-mock 两次,每个导入它们的新文件一次。
抛出的错误是:
Error: [$injector:modulerr] Failed to instantiate module ngLocale due to: RangeError: Maximum call stack size exceeded
快速 Google 搜索产生了很多关于这个问题的线程 - 说当 Karma 加载 ng-mock 两次时会弹出这个错误。 此外,调试 Chrome 上的代码确认是 ngMock 未能初始化,并且 Angular 产生警告 Angular 被加载两次。
我该怎么办? 在我看来,业力似乎分开对待每个测试文件,所以它不使用 Webpack 将 Angular 捆绑到一个模块中,而是单独编译每个文件并添加 Angular 和 ng-mock再次。
我走了一条不同的路,想不出如何解决这个问题。
我的 webpack 配置现在有这个:
entry: { entry: './app/scripts/main.ts'},
output: {
filename: isDev ? "[name].js" : '[name]-[hash].js',
path: path.resolve('dist'),
pathinfo: isDev
},
...
if (isDev) {
module.exports.devtool = 'source-map';
module.exports.entry.test = './test/test-main.ts';
}
而且我在 Karma 配置中删除了所有 webpack 的东西。
我告诉 Webpack 编译另一个包,带有一个简单的入口点 TS 文件,内容如下:
Import((<any>require).context('../app/scripts/', true, /.*\.test\.ts$/i), (_: any) => {});
Karma 正在观察输出包文件的变化。
我通过添加包含所有使用 angular-mock 的测试的 angular-services.test.ts
文件解决了这个问题。例如,他们在每个内部使用 angular.mock.module
和 inject
方法。
angular-services.test.ts内容:
import 'angular';
import 'angular-mocks';
import 'test_angular_service_1.test'
import 'test_angular_service_2.test'
.
.
import 'test_angular_service_n.test'