假设我有一个简单的模块constructor(private route: ActivatedRoute){}
,它有许多导入,声明和提供程序。现在我想为组件AppModule
编写一个测试,该组件位于此模块的声明列表中。 ListComponent
本身使用ListComponent
的许多(但不是每个)导入。我是这样做的:
AppModule
它有效,但肯定是一种不正确的方法。我不想复制粘贴这么多。也许我可以用一些方便的方法重用AppModule?伪代码就像:
import { TestBed } from '@angular/core/testing';
// +same copy-pasted list of imports from `AppModule`
beforeEach(done => {
TestBed.configureTestingModule({
imports: [
// +same copy-pasted list of imports from `AppModule`
],
declarations: [
// +same copy-pasted list of declarations from `AppModule`
],
providers: [
{
provide: Http,
useClass: HttpMock,
},
{
provide: Router,
useClass: RouterMock,
}
// +same copy-pasted list of providers from `AppModule`
]
});
但我只是不知道/找不到这种方法的语法:(
答案 0 :(得分:5)
您可以创建可重用的const,其中包含所需模块的commom导入和提供程序。
例如在app.providers.ts文件中,您可以让您的提供商这样:
import service1 from '.path/service/service1';
import service2 from '.path/service/service2';
export const providers = [service1, service2 ];
以及app.imports.ts中的导入
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { Module1} from ''.path/service/module1';
export const imports= [
BrowserModule,
AppRoutingModule,
Module1
],
并在您的app.module.ts和任何其他模块上,您希望使用相同的导入和提供程序:
import { providers } from './app.providers';
import { imports } from './app.imports';
@NgModule({
declarations: [AppComponent],
imports: imports,
providers: providers,
bootstrap: [AppComponent]
})
您还可以使用点差运算符将您的唯一导入添加到特定模块上的这些共享导入。
答案 1 :(得分:0)
通过创建全局TestBed,可以避免提供嵌套服务和依赖项的长列表。
虽然为提供者和导入创建常量数组是解决此问题的一种方法,但我想将其带到下一步,并在全局级别配置TestBed,以避免导入重复的模块。
为了配置全局TestBed,我创建了一个公共测试模块,该模块具有用于配置测试床的实用方法。然后可以在所有规范文件中重用此方法。
public static setUpTestBed = (TestingComponent: any) => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
ReactiveFormsModule,
...
],
providers: [
...
],
declarations: [TestingComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
});
}
CommonTestingModule:包含用于创建测试平台的实用方法。
LoginComponent:login.component.spec.ts->对实用程序方法的引用
CommonTestingModule.setUpTestBed(LoginComponent);
下面提供了完整的组件供参考:
CommonTestingModule:
import { ChangeDetectionStrategy, CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { DatePipe } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { UtilityService } from '../services/utility.service';
import { TestBed } from '@angular/core/testing';
@NgModule({
declarations: []
})
export class CommonTestingModule {
public static setUpTestBed = (TestingComponent: any) => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
ReactiveFormsModule,
FormsModule,
HttpClientTestingModule,
RouterTestingModule,
... //other imports
],
providers: [
DatePipe,
UtilityService,
... //other imports
],
declarations: [TestingComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
});
}
}
然后在所有组件规格文件中,您现在都可以引用实用程序方法 CommonTestingModule.setUpTestBed(),该方法接受调用组件的名称作为输入参数。
login.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LoginComponent } from './login.component';
import { CommonTestingModule } from 'src/app/testing/common-testing.module';
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
CommonTestingModule.setUpTestBed(LoginComponent);
beforeEach(() => {
// create component and test fixture
fixture = TestBed.createComponent(LoginComponent);
// get test component from the fixture
component = fixture.componentInstance;
component.ngOnInit();
});
it('Component instantiated successfully', () => {
expect(component).toBeTruthy();
});
});
就是这样。现在,您可以在所有规格文件中重复使用该实用程序方法。如果更适合您,您还可以创建一个beforeAll实用程序方法。