【问题标题】:Angular Testing Modules and override角度测试模块和覆盖
【发布时间】:2019-08-12 14:19:00
【问题描述】:

我是角度测试的初学者,我的问题可能是“角度测试最佳实践”的一部分。

我正在寻找一种在测试中包含最小模块并覆盖需要我嘲笑的部分的方法。

假设我有一个需要路由器工作的按钮组件。它的模块是这样的:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyButtonComponent } from './mybutton.component';
import { Router } from '@angular/router';
@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [
    MyButtonComponent,
  ],
  exports: [
    MyButtonComponent,
  ],
  providers: [
    Router,
  ]
})
export class MyButtonModule { }

现在我想像这样测试它:

import { TestBed, ComponentFixture } from '@angular/core/testing';
import { MyButtonModule } from './viewer-button.module';
import { RouterTestingModule } from '@angular/router/testing';

// Tests Begining
describe('ViewerButtonComponent', () => {
  let component: MyButtonComponent;
  let fixture: ComponentFixture<MyButtonComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        ViewerButtonModule,
        RouterTestingModule.withRoutes([]),
      ],
    })
    .compileComponents();

    fixture = TestBed.createComponent(MyButtonComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

  });

  it('#should create the component', () => {
    expect(component).toBeTruthy(' fail at creation');
  });
});

但是Router 并没有覆盖RouterTestingModule 导入。 (得到Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?, ?). 错误)

我知道此示例的更好方法是仅声明 MyButtonComponent,然后导入 RouterTestingModule,但我想问是否有一种方法可以在没有 NO_ERRORS_SCHEMAshallow 的情况下使用更大的组件来做到这一点。

例如:

 beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        // my childs component module
        MyChildComponentModule1,
        MyChildComponentModule2,
        ...
        MyChildComponentModuleX,

        //the modules that mock what needed (or use custom mock in the providers part)
        RouterTestingModule,
        HttpClientTestingModule,
        ....
        SomethingTestingModule
      ],
    })
    .compileComponents();

    fixture = TestBed.createComponent(MyButtonComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

  });

【问题讨论】:

    标签: angular testing module karma-jasmine


    【解决方案1】:

    RouterTestingModule 用于存根路由和导航。

    这里有几点:

    1) 您不应该在您的小部件模块中自己提供Router。相反,您应该将RouterModule.forRoot() 添加到AppModule,这将提供Router 服务及其依赖项。

    2) 你不应该创建混合的 Angular 模块,这意味着不要在单个 Angular 模块中提供和声明。

    3) Angular 模块导入顺序很重要。使用此导入顺序,RouterTestingModule 的提供程序将覆盖来自ViewButtonModule 的Router 提供程序。

    TestBed.configureTestingModule({
      imports: [
        ViewerButtonModule,
        RouterTestingModule.withRoutes([]),
      ],
    });
    

    4) 您始终可以使用 Angular 测试模块覆盖提供程序。例如

    TestBed.overrideProvider(Router, { useValue: routerStub });
    

    或

    TestBed.configureTestingModule({
      providers: [
        { provide: Router, useValue: routerStub },
      ],
    });
    

    如果你有兴趣了解更多,可以保留我的文章Testing and Faking Angular Dependencies,作为那些难以记住的细节的参考。

    2020 年我写了这些文章:

    【讨论】:

      猜你喜欢
      • 2017-11-29
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 2017-08-19
      相关资源
      最近更新 更多