TestBed configureTestingModule 在一个模块中定义所有 spec.ts 通用的导入、声明、提供程序和管道 - 模式

Posted

技术标签:

【中文标题】TestBed configureTestingModule 在一个模块中定义所有 spec.ts 通用的导入、声明、提供程序和管道 - 模式【英文标题】:TestBed configureTestingModule define imports, declarations, providers, and pipes common to all spec.ts in one Module - pattern 【发布时间】:2017-09-05 06:09:32 【问题描述】:

是否有一种最佳方式来定义所有 spec.ts 共有的导入、声明、提供程序(即所有规范共有的模块在一个地方定义,就像我们在 @NgModule 中所做的那样)在一个地方我们在@NgModule 中为应用程序单元测试 做。

注意:在 beforeEach 中调用 configureTestingModule 以便 TestBed 可以在每次测试运行之前将自身重置为基本状态。和文档一样

在我的一个测试 spec.ts 中,我必须加载相同的模块组件和指令 ..etc,这也被其他一些规范使用。

describe('Component: Login', () => 
let loginFixture, loginComponent, loginComponentElement,loginComponentDebugElement;
beforeEach(async(() => 
TestBed.configureTestingModule(
  imports: [FormsModule, ReactiveFormsModule, MaterialRootModule, ModalModule, DatepickerModule,
    DropdownModule, AccordionModule], //--> here we load n number of mudoles 
  declarations: [LoginComponent, LoginHeaderComponent, LoginColumnComponent, LoginColumnContentComponent,
    LoginStatusLaneComponent, LoginSettingsComponent,
    LoginLaneComponent, SortableDirective, WindowHeightDirective, ConfirmDirective, ConfirmPopoverComponent, ConfirmationDialogComponent,
    ConfirmationDialogDirective],         //--> here we load n number of components directive and piper          
  providers: [LoginComponent,
    MockBackend,
    BaseRequestOptions,
    ComponentLoaderFactory,
    ConfirmOptions,
    
      provide: Http,
      useFactory: (backend, options) => new Http(backend, options),
      deps: [MockBackend, BaseRequestOptions]
    ,
    provide: AuthService, useClass: MockAuthService,
    provide: AppContextService, useClass: MockAppContextService,
    provide: NotificationsService, useClass: MockNotificationsService,
    provide: PositioningService]       //--> here we load n number of services    
).compileComponents();
loginFixture = TestBed.createComponent(LoginComponent);
loginComponent = loginFixture.componentInstance; 
loginComponentElement = LoginFixture.nativeElement;
loginComponentDebugElement = LoginFixture.debugElement;
));

 it('should have a defined component', () => 
expect(LoginComponent).toBeDefined();
);
);

注意:Git Angular issue TestBed.configureTestingModule Performance Issue

在运行所有 spec.ts 文件并为每个 specs 注入各自的依赖项之前,是否有任何模式可以使其变得通用,例如在启动时加载所有这些模块组件等。任何帮助都会很棒。

【问题讨论】:

我也有同样的想法。我问过 SOja。 ja.***.com/questions/34780(截至 5 月 22 日没有回复。如果我得到任何信息,请在此处分享。) 【参考方案1】:

我的回答不完整,你已经预料到了。 不过希望能帮到你一点点。

路由器存根.ts

//----------Default Import------------
import  BrowserModule  from '@angular/platform-browser';
import  FormsModule  from '@angular/forms';
import  HttpModule  from '@angular/http';
import  BrowserAnimationsModule  from '@angular/platform-browser/animations';
...snip...
export const test_imports = [
               BrowserModule,
               FormsModule,
               HttpModule,
               BrowserAnimationsModule
             ];

每个 test.spec.ts

import  test_imports    from '../testing/router-stubs';
..snip..
      imports: [test_imports],

但提供者/声明不能以相同的方式使用。

【讨论】:

【参考方案2】:

您需要在 describe 方法之前定义 TestBed.configureTestingModule。所以它可以在全球范围内使用。所以现在您的测试用例将如下所示。

TestBed.configureTestingModule(
  imports: [FormsModule, ReactiveFormsModule, MaterialRootModule, ModalModule, DatepickerModule,
    DropdownModule, AccordionModule], //--> here we load n number of mudoles 
  declarations: [LoginComponent, LoginHeaderComponent, LoginColumnComponent, LoginColumnContentComponent,
    LoginStatusLaneComponent, LoginSettingsComponent,
    LoginLaneComponent, SortableDirective, WindowHeightDirective, ConfirmDirective, ConfirmPopoverComponent, ConfirmationDialogComponent,
    ConfirmationDialogDirective],         //--> here we load n number of components directive and piper          
  providers: [LoginComponent,
    MockBackend,
    BaseRequestOptions,
    ComponentLoaderFactory,
    ConfirmOptions,
    
      provide: Http,
      useFactory: (backend, options) => new Http(backend, options),
      deps: [MockBackend, BaseRequestOptions]
    ,
    provide: AuthService, useClass: MockAuthService,
    provide: AppContextService, useClass: MockAppContextService,
    provide: NotificationsService, useClass: MockNotificationsService,
    provide: PositioningService]       //--> here we load n number of services    
).compileComponents();

describe('Component: Login', () => 
  let loginFixture, loginComponent, loginComponentElement, loginComponentDebugElement;
  beforeEach(async(() => 

    loginFixture = TestBed.createComponent(LoginComponent);
    loginComponent = loginFixture.componentInstance;
    loginComponentElement = LoginFixture.nativeElement;
    loginComponentDebugElement = LoginFixture.debugElement;
  ));

  it('should have a defined component', () => 
    expect(LoginComponent).toBeDefined();
  );
);

【讨论】:

【参考方案3】:

没有必要仅仅为了实现这一点而去寻找一个单独的库。您可以通过创建一个通用的 Angular 模块来创建一个全局 TestBed,您可以在其中定义一个实用程序方法。此实用程序方法创建了 TestBed,然后您可以在所有规范文件中重复使用它。

您可以参考下面的答案,其中还包括示例代码:(可能重复)https://***.com/a/64835814/4184651

【讨论】:

以上是关于TestBed configureTestingModule 在一个模块中定义所有 spec.ts 通用的导入、声明、提供程序和管道 - 模式的主要内容,如果未能解决你的问题,请参考以下文章

为 TestBed 提供“entryComponents”

TestBed.get 和 new Service(...dependencies) 有啥区别

如何测试 angular 2 组件,其中嵌套组件具有自己的依赖项? (TestBed.configureTestingModule)

基于QNX的Testbed单元测试环境配置过程

使用 Testbed 的 Nativescript 测试不起作用

将 TypeMoq 模拟与 Angular TestBed 一起使用