2017-01-02 168 views
5

我剛剛開始使用Unit-Testing,並且我已經能夠模擬我自己的服務以及一些Angular和Ionic,但是不管我做什麼ChangeDetectorRef保留相同。Angular 2:如何在單元測試時模擬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, 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 ?? 
    }) 
)); 

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

我已經嘗試了一切,asyncfakeAsyncinjector([ChangeDetectorRef],() => {})

沒有用。

+0

的ChangeDetectorRef由角2編譯器給予特殊待遇。我認爲你不能提供它。您可以AsyncPipe https://github.com/angular/angular/blob/8f5dd1f11e6ca1888fdbd3231c06d6df00aba5cc/modules/%40angular/common/test/pipes/async_pipe_spec.ts有用於SpyChangeDetectorRef – yurzui

+0

我打同樣的問題,檢查測試 - 如何有人在爲此工作嗎? – SamF

回答

6

萬一有人運行到這一點,這是爲我工作很好的一種方法:

當你在注入ChangeDetectorRef比如在你的構造:

constructor(private cdRef: ChangeDetectorRef) { } 

您有cdRef爲一體的組件上的私有屬性,這意味着你可以監視組件,存儲該屬性並讓它返回你想要的任何東西。此外,您可以根據需要斷言它的調用和參數。

在你的spec文件中,調用你的TestBed而不提供ChangeDetectorRef,因爲它不會提供你給它的東西。設置相同的beforeEach塊組件,所以它是因爲它是在文檔here進行規範之間復位:

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中,因此它是可訪問的。

,如果你想在運行時爲您的測試訪問私有屬性這樣,它是給你。我個人並沒有任何問題,我按照我的規格做了更多的報道。