2017-01-02 8 views
5

単体テストを始めたばかりですが、自分のサービスや角度やイオンもモックできましたが、何をしてもChangeDetectorRefは同じ。角2:単体テスト時にChangeDetectorRefを模擬する方法

これはどの種類の魔術師ですか?


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(); 
} 
} 

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, useClass: ChangeDetectorRefMock}, 
     ] 
     } 
    }) 
    .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 ?? 
    }) 
)); 

asyncfakeAsyncinjector([ChangeDetectorRef],() => {})

何も機能しません。

+0

ChangeDetectorRefには、Angular 2コンパイラによって特別な処理が与えられます。私はあなたがそれを提供することはできないと思う。 AsyncPipeのテストを確認することができます。https://github.com/angular/angular/blob/8f5dd1f11e6ca1888fdbd3231c06d6df00aba5cc/modules/%40angular/common/test/pipes/async_pipe_spec.ts SpyChangeDetectorRefが使用されています – yurzui

+0

私は同じ問題を抱えています。これを回避しようとしているのは誰ですか? – SamF

答えて

6

誰もこれに実行される場合には、これは私のためによく働いている1つの方法です:あなたは、コンストラクタでChangeDetectorRefインスタンスを注入されたよう

constructor(private cdRef: ChangeDetectorRef) { } 

あなたはcdRef一つとしてことを持っていますそれはあなたがコンポーネントを偵察し、その属性をスタブし、あなたが望むものを返すことを意味します。また、必要に応じて、呼び出しやパラメータをアサートすることもできます。

スペックファイルで、あなたが与えるものを提供しないので、ChangeDetectorRefを指定せずにTestBedに電話してください。コンポーネント同じbeforeEachブロックを設定し、それはそれはドキュメントhereで行われるようにスペックの間にリセットされます。スパイと直接属性

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

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

に、テストでその後

component = fixture.componentInstance; 

スパイ.and.returnValue()を使用して、必要なものを返すことができます。

cdRefはプライベート属性であるため、(component as any)が使用されています。しかしプライベートは実際のコンパイルされたjavascriptには存在しないのでアクセス可能です。

テストのために実行時にプライベート属性にアクセスする場合は、あなたに任せます。私は個人的にそれに何ら問題はありません、私はより多くのカバレッジを得るために私の仕様でそれを行います。

関連する問題