如何重用 Angular 测试文件中的所有导入
Posted
技术标签:
【中文标题】如何重用 Angular 测试文件中的所有导入【英文标题】:How to reuse all imports in Angular test files 【发布时间】:2018-07-25 03:36:22 【问题描述】:假设我有一个简单的模块AppModule
,它有许多导入、声明和提供程序。现在我想为位于该模块声明列表中的组件ListComponent
编写一个测试。 ListComponent
本身使用了许多(但不是所有)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`
]
);
它有效,但肯定是不正确的方法。我不想复制粘贴这么多。也许我可以以某种方便的方式重用 AppModule?伪代码如下:
let appModule = new AppModule();
beforeEach(done =>
TestBed.configureTestingModule(
imports: appModule.imports,
declarations: appModule.declarations,
providers: [...appModule.providers,
provide: Http,
useClass: HttpMock,
,
provide: Router,
useClass: RouterMock,
]
);
但我只是不知道/找不到这种方法的语法:(
【问题讨论】:
【参考方案1】:您可以创建可重用的 const,其中包含您想要的模块中的常用导入、提供程序。
例如,在 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]
)
您还可以使用扩展运算符将您的唯一导入添加到特定模块上的这些共享导入中。
【讨论】:
谢谢,这正是我需要的。 我想知道,为什么这种方法不是默认的角度?为什么需要为每个规范写出导入、提供程序和声明?【参考方案2】:您可以通过创建全局 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 实用方法。
【讨论】:
以上是关于如何重用 Angular 测试文件中的所有导入的主要内容,如果未能解决你的问题,请参考以下文章