Angular2 单元测试:测试组件的构造函数

Angular2 unit testing : testing a component's constructor

一切都在标题中:如何测试组件的构造函数中所做的事情?

供您参考,我正在使用需要设置的服务,我想看看我在构造函数中调用的 2 个方法是否被正确调用。

我的组件的构造函数:

constructor(
  public router: Router,
  private profilService: ProfileService,
  private dragula: DragulaService,
  private alerter: AlertService
) {
  dragula.drag.subscribe((value) => {
    this.onDrag(value);
  });
  dragula.dragend.subscribe((value) => {
    this.onDragend(value);
  });
}

我会使用 DI 系统注入虚假服务,这意味着编写如下测试:

describe('your component', () => {
  let fixture: ComponentFixture<YourComponent>;
  let fakeService;
  let dragSubject = new ReplaySubject(1);
  ...

  beforeEach(async(() => {
    fakeService = { 
      drag: dragSubject.asObservable(),
      ... 
    };

    TestBed.configureTestingModule({
      declarations: [YourComponent, ...],
      providers: [
        { provide: DragulaService, useValue: fakeService }, 
        ...
      ],
    });
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(YourComponent);
    fixture.detectChanges();
  });

  it('should do something when a drag event occurs', () => {
    dragSubject.next({ ... });
    fixture.detectChanges();
    ...
  });
});

这允许您随时通过调用主题上的 .next 来触发 "drag events",这会导致虚假服务字段的订阅者被调用。然后你可以对你期望的结果做出断言。

请注意,您不需要自己调用 constructor;当 DI 系统实例化您的组件时,即调用 TestBed.createComponent 时调用此方法。

我建议您 不要 监视组件方法(例如 this.onDrag),只要确保它们被调用即可,而是测试任何这些方法应该在结果发生时执行;这使得测试对特定实现中的更改更加健壮(我在我的博客上写了一些关于这个的内容:http://blog.jonrshar.pe/2017/Apr/16/async-angular-tests.html)。

在构造函数中测试任何内容的简单方法是创建组件实例,然后对其进行测试。

it('should call initializer function in constructor', () => {
  TestBed.createComponent(HomeComponent); // this is the trigger of constructor method
 expect(sideNavService.initialize).toHaveBeenCalled(); // sample jasmine spy based test case
});

需要注意的一点是,如果你想区分constructor和ngOnInit,那就不要在beforeEach()里面调用fixture.detectChanges()。而是在需要时手动调用。

既然 OP 说 "I would like to see if the 2 methods that I call in the constructor are called correctly." 我有更好的方法。

编写单元测试。您不需要为此使用测试台。它会大大减慢您的测试速度。手动实例化您的模拟。在您感兴趣的方法上设置您的间谍,然后使用您已经实例化并设置间谍的存根手动调用组件构造函数。然后测试是否正确调用了间谍方法。

关键是从原始服务扩展您的存根 类。 jasmine.createSpyObj 有助于模拟 angular 类 就像 Router.