是否可以测试一个类的私有方法?

时间:2017-10-24 18:22:56

标签: angular unit-testing karma-jasmine

在我的Ionic 3(Angular 4)应用程序中,我有这段代码:

this.$observable.subscribe(success => {
  if (success) {
    this.toastCtrl.create({
      message: 'message,
      duration: 3000,
      position: 'middle'
    }).present();
  }
});

我想测试的是toastCtrl是否会$observable发出success = true

这是我的测试结果:

it('when true, show toast', done => {
  fixture.whenStable().then(() => {
    component.$observable.subscribe(success => {
      if (success) {
        fixture.detectChanges();
        console.log(debugElement.query(By.css('.toast-message')));
        done();
        // expect(debugElement.query(By.css('.toast-message')).nativeElement).toBeDefined();
      }
    });
  });
});

然而无法正常工作因为生成吐司可能有一些延迟(注意:我正在使用Ionic Native,但该类的元素实际上是插入DOM中的 - 尽管只用了3秒钟,我甚至尝试了100秒)

我是否在测试异步代码中做错了什么?

如果没有,如何测试this.toastCtrl被称为(显然我不能,因为它是组件中的私有属性 - 因为必须让它工作,因为它被注入在构造函数中作为...

constructor(private toastCtrl: ToastController)

1 个答案:

答案 0 :(得分:3)

您可以使用spyOn通过传递来测试它。

您也可以尝试(component as any).privateMethodcomponent['privateMethod']可能也会起作用。

如果私有方法不需要访问this,您可以将它放在课外,无论如何都应该这样做。

理论上,您可以公开仅在定义jasmine时才有效的公共版本:

public foo() {
  if (!jasmine) throw new Error("can't call this unless testing!"); 
  return bar();
}

private bar() {
  return 42;
}

关于SO的许多其他问题都涉及到这个问题,尤其是试图测试内部函数的矛盾概念,内部函数应该是内部函数,因此可能是一些黑盒子。