在 Angular 中正确使用 TestBed
Correct using of TestBed in Angular
在一个基于 Angular 8.1.2 和 Ionic 4 的应用程序项目中,我用打字稿为一个简单的 class 编写了单元测试。这对 "npm test" 很好。为了为需要模拟的更复杂的 classes 做准备,我更改了代码,以这种方式使用 beforeEach 方法和 TestBed 对象:
import { CryptHelper, CryptCodeTyp, CryptIOStringTyp } from './cryptHelper';
import { TestBed } from '@angular/core/testing';
describe('CryptHelper', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ CryptHelper ],
imports: [ ],
providers: [ CryptHelper ],
}).compileComponents();
});
it('should be created', () => {
let fixture = TestBed.createComponent(CryptHelper);
let app = fixture.debugElement.componentInstance;
expect(app).toBeDefined();
});
});
这样我在测试输出中得到了错误信息
error properties: Object({ ngSyntaxError: true })
Error: Unexpected value 'CryptHelper' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.
at syntaxError (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:2175:1)
at http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19889:1
at <Jasmine>
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19871:1)
at JitCompiler._loadModules (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25582:1)
at JitCompiler._compileModuleAndAllComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25571:1)
at JitCompiler.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25533:1)
at CompilerImpl.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/platform-browser-dynamic.js:237:1)
at TestingCompilerImpl.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/testing.js:140:1)
at TestBedViewEngine.compileComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3118:1)
我发现建议从声明中删除 class 名称,
...
TestBed.configureTestingModule({
declarations: [ ],
...
但这导致我收到此错误消息:
error properties: Object({ ngSyntaxError: true })
Error: Illegal state: Could not load the summary for directive CryptHelper.
at syntaxError (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:2175:1)
at CompileMetadataResolver.getDirectiveSummary (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19729:1)
at JitCompiler.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25536:1)
at CompilerImpl.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/platform-browser-dynamic.js:263:30)
at TestingCompilerImpl.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/testing.js:148:1)
at TestBedViewEngine.createComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3418:1)
at Function.createComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3000:1)
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/core/services/cryptHelper.spec.ts:15:27)
at <Jasmine>
我找到了在声明中写下 class 名称的建议。但这导致我看到上面的错误消息。那我做错了什么?欢迎任何帮助。
假设 CryptHelper 是一个组件:
TestBed.configureTestingModule({
declarations: [ CryptHelper], // Your testing component goes here
providers: [ // Your component's providers goes here, for example a mocked service
{
provide: MyService, useValue: mockMyService
}
],
imports: [
// imports from your component, for example MatDialogModule, MatInputModule, MyComponentModule, ...
]
})
.compileComponents();
假设 CryptHelper 是一个服务:
let cryptHelper: CryptHelper;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [CryptHelper],
imports: []
});
cryptHelper = TestBed.get(CryptHelper);
});
describe('CryptHelper Service creation', () => {
it('should be created', inject([CryptHelper], (service: CryptHelper) => {
expect(service).toBeTruthy();
}));
});
正如您的日志所说,CryptHelper 不是一个组件。所以正确的测试是将它用作服务(如果您希望像 DI 元素一样使用它)。
这是工作示例:
describe('CryptHelper', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ CryptHelper ],
});
});
it('should be created', () => {
let fixture = TestBed.get(CryptHelper);
let app = fixture.debugElement.componentInstance;
expect(app).toBeDefined();
});
});
你可以注意到 TestBed.get
被用来代替 TestBed.createComponent
在一个基于 Angular 8.1.2 和 Ionic 4 的应用程序项目中,我用打字稿为一个简单的 class 编写了单元测试。这对 "npm test" 很好。为了为需要模拟的更复杂的 classes 做准备,我更改了代码,以这种方式使用 beforeEach 方法和 TestBed 对象:
import { CryptHelper, CryptCodeTyp, CryptIOStringTyp } from './cryptHelper';
import { TestBed } from '@angular/core/testing';
describe('CryptHelper', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ CryptHelper ],
imports: [ ],
providers: [ CryptHelper ],
}).compileComponents();
});
it('should be created', () => {
let fixture = TestBed.createComponent(CryptHelper);
let app = fixture.debugElement.componentInstance;
expect(app).toBeDefined();
});
});
这样我在测试输出中得到了错误信息
error properties: Object({ ngSyntaxError: true })
Error: Unexpected value 'CryptHelper' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.
at syntaxError (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:2175:1)
at http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19889:1
at <Jasmine>
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19871:1)
at JitCompiler._loadModules (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25582:1)
at JitCompiler._compileModuleAndAllComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25571:1)
at JitCompiler.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25533:1)
at CompilerImpl.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/platform-browser-dynamic.js:237:1)
at TestingCompilerImpl.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/testing.js:140:1)
at TestBedViewEngine.compileComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3118:1)
我发现建议从声明中删除 class 名称,
...
TestBed.configureTestingModule({
declarations: [ ],
...
但这导致我收到此错误消息:
error properties: Object({ ngSyntaxError: true })
Error: Illegal state: Could not load the summary for directive CryptHelper.
at syntaxError (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:2175:1)
at CompileMetadataResolver.getDirectiveSummary (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19729:1)
at JitCompiler.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25536:1)
at CompilerImpl.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/platform-browser-dynamic.js:263:30)
at TestingCompilerImpl.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/testing.js:148:1)
at TestBedViewEngine.createComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3418:1)
at Function.createComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3000:1)
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/core/services/cryptHelper.spec.ts:15:27)
at <Jasmine>
我找到了在声明中写下 class 名称的建议。但这导致我看到上面的错误消息。那我做错了什么?欢迎任何帮助。
假设 CryptHelper 是一个组件:
TestBed.configureTestingModule({
declarations: [ CryptHelper], // Your testing component goes here
providers: [ // Your component's providers goes here, for example a mocked service
{
provide: MyService, useValue: mockMyService
}
],
imports: [
// imports from your component, for example MatDialogModule, MatInputModule, MyComponentModule, ...
]
})
.compileComponents();
假设 CryptHelper 是一个服务:
let cryptHelper: CryptHelper;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [CryptHelper],
imports: []
});
cryptHelper = TestBed.get(CryptHelper);
});
describe('CryptHelper Service creation', () => {
it('should be created', inject([CryptHelper], (service: CryptHelper) => {
expect(service).toBeTruthy();
}));
});
正如您的日志所说,CryptHelper 不是一个组件。所以正确的测试是将它用作服务(如果您希望像 DI 元素一样使用它)。 这是工作示例:
describe('CryptHelper', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ CryptHelper ],
});
});
it('should be created', () => {
let fixture = TestBed.get(CryptHelper);
let app = fixture.debugElement.componentInstance;
expect(app).toBeDefined();
});
});
你可以注意到 TestBed.get
被用来代替 TestBed.createComponent