2017-06-16 277 views
3

我想測試一個異步組件方法,我想我正確地使用了Angular 4的異步測試功能,但它不工作。我的問題是,當我運行測試時,不等待供Promise解決。看起來,函數的異步特性導致超時被觸發,並且測試過早退出。無論如何,測試都會通過,因爲whenStable()中的所有expect()語句都會被跳過。爲什麼我的異步Angular Jasmine單元測試不工作?

如果我省略了async()包裝功能和開關傳遞一個done回調,並在whenStable()塊的末尾調用它的茉莉花語法,它工作正常。誰能告訴我爲什麼它不適用於Angular async()包裝?

我的代碼如下所示:

// my.component.ts 
ngOnInit() { 
    this.getResults().then((results) => { 
    this.results = results; 
    }); 
} 

// My asynchronous function, which takes 1.5s to load results 
getResults() { 
    let promise = new Promise((resolve) => { 
    setTimeout(() => { 
     resolve('foo'); 
    }, 1500); 
    }) 
    return promise; 
} 


// my.component.spec.ts (Angular async version which doesn't work) 
it('should load results', async(() => { 
    spyOn(component, 'getResults').and.returnValue(Promise.resolve('bar')); 
    component.ngOnInit(); 

    fixture.whenStable().then(() => { 
    // Everything in here gets skipped when I run the test 
    fixture.detectChanges(); 
    // This should cause the test to fail, but it doesn't because it's not run in time 
    expect(true).toBe(false) 
    }); 
})); 

// my.component.spec.ts (Jasmine version that works) 
it('should load results', (done) => { 
    spyOn(component, 'getResults').and.returnValue(Promise.resolve('bar')); 
    component.ngOnInit(); 

    fixture.whenStable().then(() => { 
    fixture.detectChanges(); 
    // This should fail and it does because the test works using Jasmine's "done" callback 
    expect(true).toBe(false); 
    done(); 
    }); 
}); 
+0

嘗試調用'夾具。 detectChanges();'而不是'component.ngOnInit();'它也會運行'ngOnInit()',因爲這是你第一次調用它。 –

+0

這裏有什麼問題? https://plnkr.co/edit/MIDy85L9fVOtdvyXKnuS?p=preview你'getResult()'方法不會被執行,因爲你嘲笑它 – yurzui

+0

@AmitChigadani謝謝,但這並不行。 '期望(true).toBe(false)'仍然通過。 – Stewart

回答

3

感謝@ yurzui的Plunker,我確定,我的問題是我在我的beforeEach()方法調用fixture.detectChanges()造成的:

beforeEach(() => { 
    TestBed.configureTestingModule({ 
     declarations: [AppComponent], 
    }); 

    fixture = TestBed.createComponent(AppComponent); 

    component = fixture.componentInstance; 

    // The following line is to blame! Removing it makes the test work correctly. 
    fixture.detectChanges(); 
}); 
+0

無論如何找出夾具的原因。 detectChanges()'不能在'BeforeEach()' –

+1

@AdamHughes這是因爲在我的情況下,我需要阻止'ngOnInit()'運行。 detectChanges()會導致該方法運行。 – Stewart