2016-11-14 126 views
2

我是新來的測試世界,我剛開始爲現有的Angular 2代碼編寫單元測試。我有一個功能confirmDelete,它返回Obserable<boolean>並在內部使用PrimeNG的ConfirmationService以獲得用戶對彈出窗口的反饋。該函數的單元測試角度觀察

定義在下面給出:

confirmDelete(): Observable<boolean> { 
    let confirmObservable = Observable.create((observer: Observer<boolean>) => {    
     this.confirmationService.confirm({ 
      header: 'Delete Confirmation', 
      message: 'Do you really want to delete this record?', 
      accept:() => { 
       observer.next(true); 
       observer.complete();    
      }, 
      reject:() => { 
       observer.next(false); 
       observer.complete(); 
      } 
     }); 

    }); 

    return confirmObservable; 

} 

我想要寫這段代碼單元測試。我計劃爲ConfirmationService編寫一個存根,但由於我是單元測試領域的新手,我發現很難設置這些東西。

我的問題是在這個特定場景中編寫單元測試的正確方法是什麼。

編輯: -

我試圖通過@peeskillet提出的解決方案,但後來我開始越來越ConfirmationServiceMockConfirmationService之間的類型不匹配錯誤。

以下是在PrimeNG庫中找到的ConfirmationServiceConfirmation類的聲明。

export interface Confirmation { 
    message: string; 
    icon?: string; 
    header?: string; 
    accept?: Function; 
    reject?: Function; 
    acceptVisible?: boolean; 
    rejectVisible?: boolean; 
    acceptEvent?: EventEmitter<any>; 
    rejectEvent?: EventEmitter<any>; 
} 
export declare class ConfirmationService { 
    private requireConfirmationSource; 
    private acceptConfirmationSource; 
    requireConfirmation$: Observable<Confirmation>; 
    accept: Observable<Confirmation>; 
    confirm(confirmation: Confirmation): this; 
    onAccept(): void; 
} 

回答

3

我很可能會令到的acceptreject功能引用模擬舉行。然後在測試中,您可以調用它們來檢查它們是否發出正確的布爾值。像

class MockConfirmationService { 
    accept: Function; 
    reject: Function; 

    confirm(config: any) { 
    this.accept = config.accept; 
    this.reject = config.reject; 
    } 
} 

然後在你測試的東西只是調用accept來測試true發出,並呼籲reject來測試false被髮射。

describe('serivce: ModalService',() => { 

    let modalService: ModalService; 
    let confirmService: MockConfirmationService; 

    beforeEach(() => { 
    confirmService = new MockConfirmationService(); 
    TestBed.configureTestingModule({ 
     providers: [ 
     ModalService, 
     { provide: ConfirmationService, useValue: confirmService } 
     ] 
    }); 

    modalService = TestBed.get(ModalService); 
    }); 

    it('should return true when accepted', async(() => { 
    modalService.confirmDelete().subscribe(result => { 
     expect(result).toBe(true); 
     console.log('accepted test complete'); 
    }); 
    confirmService.accept(); 
    })); 

    it('should return false when rejected', async(() => { 
    modalService.confirmDelete().subscribe(result => { 
     expect(result).toBe(false); 
     console.log('rejected test complete'); 
    }); 
    confirmService.reject(); 
    })); 
}); 
+0

謝謝@ peeskillet。我嘗試了上述解決方案,但我得到了一些類型不匹配錯誤。請看我上面編輯過的帖子。 –

+0

我應該工作。我測試了它,它工作正常。完全看看我的例子。 'ModalService'只不過是一個簡單的類,它將'ConfirmationService'作爲構造參數。和方法,我從你的帖子複製並粘貼 –

+0

如果你想在不使用TestBed的情況下進行測試(只是實例化測試中的服務,並將模擬傳遞給它的構造函數),那麼你需要「投射」試圖通過它之前模擬。但是使用Testbed,我們不需要擔心這些事情,因爲類型檢查只是編譯時間 –

0

我已經建立了peeskillet的答案。該對confirmDialog組件調用該服務的訂閱,所以我不得不添加requireConfirmationSource,這是我在PrimeNg源中找到。我的模擬如下:

// 
import { Subject } from 'rxjs/Subject'; 
import { Observable } from 'rxjs/Observable'; 
// 
export class ConfirmationServiceMock { 
    public key: string = 'mock1'; 
    public header: string = 'Delete Confirmation'; 
    public icon: string = ''; 
    public message: string = ''; 
    // Call Accept to emulate a user accepting 
    public accept: Function; 
    // Call Reject to emulate a user rejecting 
    public reject: Function; 
    private requireConfirmationSource = new Subject<any>(); 
    requireConfirmation$ = this.requireConfirmationSource.asObservable(); 
    // 
    public confirm(config: any) { 
     console.log('In confirm service mock...'); 
     this.message = config.message; 
     this.accept = config.accept; 
     this.reject = config.reject; 
     console.log(this.message); 
     return this; 
    } 
} 
//