单元测试 – Angular 2:如何在单元测试时模拟ChangeDetectorRef

前端之家收集整理的这篇文章主要介绍了单元测试 – Angular 2:如何在单元测试时模拟ChangeDetectorRef前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我刚刚开始使用Unit-Testing,我已经能够模拟自己的服务以及一些Angular和Ionic,但无论我做什么,ChangeDetectorRef保持不变.

我的意思是这是什么样的巫术?

beforeEach(async(() => 
    TestBed.configureTestingModule({
      declarations: [MyComponent],providers: [
        Form,DomController,ToastController,AlertController,PopoverController,{provide: Platform,useClass: PlatformMock},{
          provide: NavParams,useValue: new NavParams({data: new PageData().Data})
        },{provide: ChangeDetectorRef,useClass: ChangeDetectorRefMock}

      ],imports: [
        FormsModule,ReactiveFormsModule,IonicModule
      ],})
    .overrideComponent(MyComponent,{
      set: {
        providers: [
          {provide: ChangeDetectorRef,useClass: ChangeDetectorRefMock},],viewProviders: [
          {provide: ChangeDetectorRef,]
      }
    })
    .compileComponents()
    .then(() => {
      let fixture = TestBed.createComponent(MyComponent);
      let cmp = fixture.debugElement.componentInstance;

      let cdRef = fixture.debugElement.injector.get(ChangeDetectorRef);

      console.log(cdRef); // logs ChangeDetectorRefMock
      console.log(cmp.cdRef); // logs ChangeDetectorRef,why ??
    })
  ));
it('fails no matter what',async(() => {
    spyOn(cdRef,'markForCheck');
    spyOn(cmp.cdRef,'markForCheck');

    cmp.ngOnInit();

    expect(cdRef.markForCheck).toHaveBeenCalled();  // fail,why ??
    expect(cmp.cdRef.markForCheck).toHaveBeenCalled(); // success

    console.log(cdRef); // logs ChangeDetectorRefMock
    console.log(cmp.cdRef); // logs ChangeDetectorRef,why ??
  }));
@Component({
  ...
})
export class MyComponent {
 constructor(private cdRef: ChangeDetectorRef){}

 ngOnInit() {
   // do something
   this.cdRef.markForCheck();
 }
}

我已经尝试了所有东西,async,fakeAsync,injector([ChangeDetectorRef],()=> {}).

什么都行不通.

万一有人碰到这个,这是一种对我有用的方法

当您在构造函数中注入ChangeDetectorRef实例时:

constructor(private cdRef: ChangeDetectorRef) { }

您将cdRef作为组件上的私有属性之一,这意味着您可以监视组件,存根该属性并让它返回您想要的任何内容.此外,您可以根据需要断言其调用和参数.

在您的spec文件中,调用您的TestBed而不提供ChangeDetectorRef,因为它不会提供您提供的内容.设置相同beforeEach块的组件,因此它在规范之间重置,因为它在文档@L_404_0@中完成:

component = fixture.componentInstance;

然后在测试中,直接监视属性

describe('someMethod()',() => {
  it('calls detect changes',() => {
    const spy = spyOn((component as any).cdRef,'detectChanges');
    component.someMethod();

    expect(spy).toHaveBeenCalled();
  });
});

有了间谍,你可以使用.and.returnValue()并让它返回你需要的任何东西.

请注意,(component as any)用作cdRef是私有属性.但私有在实际编译的JavaScript中不存在,因此可以访问.

如果您希望在运行时以这种方式访问​​测试的私有属性,则由您决定.我个人对它没有任何问题,我按照我的规格来做更多的报道.

猜你在找的Angularjs相关文章