单元测试 Angular 2 组件时,内置管道会导致失败
Inbuilt pipes cause failures when unit testing Angular 2 component
我有想要测试的示例组件。
当我使用自定义管道(例如我的自定义管道 concat
)时,它工作正常。
import { ConcatPipe } from 'path-to-concat-pipe';
@Component({
selector: 'test',
template: '{{ testProp | concat }}'
})
class TestComp {
public testProp: Array = [2017, 2018];
}
但是当我尝试使用 inbuilt pipe(例如 number
)时,我的测试失败了,没有任何信息性错误消息。
@Component({
selector: 'test',
template: '{{ testProp | number }}'
})
class TestComp {
public testProp: number = 2017;
}
示例规范代码
describe('TestComp', () => {
let comp: TestComp;
let fixture: ComponentFixture<TestComp>;
beforeEach(async(() => {
TestBed
.configureTestingModule({
declarations: [TestComp, ConcatPipe],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(TestComp);
fixture.detectChanges();
})
}));
it('TestComp successfully initialized', () => {
expect(fixture.componentInstance).toBeDefined()
});
});
此外,我尝试从“@angular/common”导入 DecimalPipe 并将其添加到声明数组,但它会导致错误
Type DecimalPipe is part of the declarations of 2 modules:
CommonModule and DynamicTestModule!
我正在使用 angular 2.0 发行版。
UPD
在@yurzui 提供的 plunker 中测试工作正常,但在我的项目中失败。我想问题可能与我的业力配置文件有关
karma.shim.js
'use strict';
Error.stackTraceLimit = Infinity;
require('es6-shim');
require('reflect-metadata');
require('zone.js/dist/zone');;
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
require('zone.js/dist/sync-test');
require('zone.js/dist/proxy');
require('zone.js/dist/jasmine-patch');
require('@angular/core/testing');
var appContext = require.context('./src', true, /root.spec.ts/);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
karma.conf.js
'use strict';
var webpackConfig = require('./webpack.config');
module.exports = function (config) {
var _config = {
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './karma-shim.js', watched: false},
{pattern: './src/app/**/*spec.ts', watched: true, included: false}
],
exclude: [],
preprocessors: {
'./karma-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
coverageReporter: {
dir: 'coverage/',
reporters: [
{type: 'text-summary'},
{type: 'html'}
]
},
browserNoActivityTimeout : 100000,
webpackServer: {
noInfo: true
},
reporters: ['story', 'coverage', 'progress'],
port: 9876,
colors: true,
logLevel: config.LOG_DEBUG,
autoWatch: false,
browsers: ['PhantomJS'],
singleRun: true,
};
config.set(_config);
};
根据文档https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-what-to-declare
我应该在声明中添加什么类?
Add declarable classes — components, directives, and pipes — to a
declarations list.
These classes must be declared in exactly one module of the
application. Declare them in this module if they belong to this
module.
所以你应该导入 CommonModule
而不是将 DecimalPipe
推送到声明数组:
TestBed.configureTestingModule({
imports: [CommonModule],
我找到了解决方案。
测试在 PhantomJS 浏览器上失败,但在 Chrome 上有效。 angular-cli 生成的项目可重现同样的问题。
为了让 angular 2 个内置管道的测试在 PhantomJS 上运行,那么应该将 2 行代码添加到
karma.shim.js 如果你使用 generator-ng2-webpack.
require('intl');
require('intl/locale-data/jsonp/en');
或
src/polyfills.ts 如果您使用 angular-cli.
import 'intl';
import 'intl/locale-data/jsonp/en';
我有想要测试的示例组件。
当我使用自定义管道(例如我的自定义管道 concat
)时,它工作正常。
import { ConcatPipe } from 'path-to-concat-pipe';
@Component({
selector: 'test',
template: '{{ testProp | concat }}'
})
class TestComp {
public testProp: Array = [2017, 2018];
}
但是当我尝试使用 inbuilt pipe(例如 number
)时,我的测试失败了,没有任何信息性错误消息。
@Component({
selector: 'test',
template: '{{ testProp | number }}'
})
class TestComp {
public testProp: number = 2017;
}
示例规范代码
describe('TestComp', () => {
let comp: TestComp;
let fixture: ComponentFixture<TestComp>;
beforeEach(async(() => {
TestBed
.configureTestingModule({
declarations: [TestComp, ConcatPipe],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(TestComp);
fixture.detectChanges();
})
}));
it('TestComp successfully initialized', () => {
expect(fixture.componentInstance).toBeDefined()
});
});
此外,我尝试从“@angular/common”导入 DecimalPipe 并将其添加到声明数组,但它会导致错误
Type DecimalPipe is part of the declarations of 2 modules: CommonModule and DynamicTestModule!
我正在使用 angular 2.0 发行版。
UPD
在@yurzui 提供的 plunker 中测试工作正常,但在我的项目中失败。我想问题可能与我的业力配置文件有关
karma.shim.js
'use strict';
Error.stackTraceLimit = Infinity;
require('es6-shim');
require('reflect-metadata');
require('zone.js/dist/zone');;
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
require('zone.js/dist/sync-test');
require('zone.js/dist/proxy');
require('zone.js/dist/jasmine-patch');
require('@angular/core/testing');
var appContext = require.context('./src', true, /root.spec.ts/);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
karma.conf.js
'use strict';
var webpackConfig = require('./webpack.config');
module.exports = function (config) {
var _config = {
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './karma-shim.js', watched: false},
{pattern: './src/app/**/*spec.ts', watched: true, included: false}
],
exclude: [],
preprocessors: {
'./karma-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
coverageReporter: {
dir: 'coverage/',
reporters: [
{type: 'text-summary'},
{type: 'html'}
]
},
browserNoActivityTimeout : 100000,
webpackServer: {
noInfo: true
},
reporters: ['story', 'coverage', 'progress'],
port: 9876,
colors: true,
logLevel: config.LOG_DEBUG,
autoWatch: false,
browsers: ['PhantomJS'],
singleRun: true,
};
config.set(_config);
};
根据文档https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-what-to-declare
我应该在声明中添加什么类?
Add declarable classes — components, directives, and pipes — to a declarations list.
These classes must be declared in exactly one module of the application. Declare them in this module if they belong to this module.
所以你应该导入 CommonModule
而不是将 DecimalPipe
推送到声明数组:
TestBed.configureTestingModule({
imports: [CommonModule],
我找到了解决方案。 测试在 PhantomJS 浏览器上失败,但在 Chrome 上有效。 angular-cli 生成的项目可重现同样的问题。
为了让 angular 2 个内置管道的测试在 PhantomJS 上运行,那么应该将 2 行代码添加到
karma.shim.js 如果你使用 generator-ng2-webpack.
require('intl');
require('intl/locale-data/jsonp/en');
或
src/polyfills.ts 如果您使用 angular-cli.
import 'intl';
import 'intl/locale-data/jsonp/en';