在Angular2测试中正确注入依赖项

时间:2016-09-30 08:53:27

标签: angular jasmine karma-jasmine angular2-testing

我正在努力测试注入了服务的Angular2组件。测试代码如下,但基本上是:

•SearchComponent在constrctor中使用FightService。

•构造函数调用flightsService.getFlights()来触发HTTP请求。 flightsService.getFlights()返回一个observable。

•构造函数订阅了返回的observable,它填充了allSummaryItems数组。

我的MockFlightService没有被使用,它基本上没有说Http没有提供者(在FlightService构造函数中)。如果我将HttpModule添加到TestBed中的提供程序,那么它会关闭并触发真正的Http请求。

如何确保我使用MockFlightService?这也会正确地测试observable,即使在发出真正的Http请求时我也可以看到订阅的方法没有被调用吗?

由于

class MockFlightsService {
  public getFlights = () => {
    return new Observable<any>(() => { return dummyData.json(); });
  };
}

describe('SearchComponent Tests', () => {
  let fixture: ComponentFixture<SearchComponent>;
  let component: SearchComponent;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [SearchComponent],
      imports: [RouterModule],
      providers: [{ provide: FlightsService, useClass: MockFlightsService }]
    });

    fixture = TestBed.createComponent(SearchComponent);
    fixture.detectChanges();
  });

  it('should render list', fakeAsync(() => {
    fixture.whenStable();
    component = fixture.componentInstance;
    console.log(component.allSummaryItems); // this is empty, shouldn't be
  }));
});

我正在使用Angular 2.0.1。

1 个答案:

答案 0 :(得分:2)

  

我的MockFlightService没有被使用,它基本上没有说Http没有提供者(在FlightService构造函数中)

使用您显示的配置,我发现这种情况的唯一方法就是您在@Component.providers中列出了该服务。这将覆盖任何模块级提供程序。我整天都在撕扯头发,因为我完全忘记了我的头发。

如果该服务应该是应用程序范围的提供者,请将其从@Component.providers中取出并添加到@NgModule.providers

如果您的目标是将服务限制在组件级别,那么您应该做的是覆盖测试组件中的提供程序,而不是将提供程序添加到测试模块中。

TestBed.overrideComponent(SearchComponent, {
  set: {
    providers: [
      { provide: FlightsService, useClass: MockFlightsService }
    ]
  }
});

这应该在创建组件之前完成。

您可以在Overriding Test Providers中看到更多内容。

其他事情与错误无关。

  • 您对RouterModule的使用。对于测试,您应该使用RouterTestingModule,如上所述here
  • whenStable返回一个承诺。只是打电话给它,并不能保护你。你需要订阅它,然后在那里做你的东西。

    whenStable().then(() => {
      // Do stuff here. This is when the async tasks are completed.
    })
    
  • 如果您需要,请查看this post,了解如何模拟Http的示例,以便您在测试期间不会发出XHR请求。< / p>