2017-06-19 85 views
1

我試圖在使用takeUntil()的Angular應用程序中正確取消訂閱Observable,但似乎打破了測試。使用takeUntil break單元測試取消訂閱Angular Observable

Chrome 58.0.3029 (Mac OS X 10.12.5) AppComponent should render title in a h1 tag FAILED 
Failed: this.appService.getGuides(...).takeUntil is not a function 
TypeError: this.appService.getGuides(...).takeUntil is not a function 
    at AppComponent.Array.concat.AppComponent.ngOnInit (webpack:///src/app/app.component.ts:28:7 <- src/test.ts:53764:14) 
    at checkAndUpdateDirectiveInline (webpack:///~/@angular/core/@angular/core.es5.js:10923:0 <- src/test.ts:11228:19) 

這是代碼:

export class AppComponent implements OnDestroy, OnInit { 
    private ngUnsubscribe: Subject<void> = new Subject<void>(); 

    title = 'app works!'; 
    guides: Guide[]; 

    constructor(private appService: AppService) { 
    } 

    ngOnInit(): void { 
    this.appService.getGuides() 
     .takeUntil(this.ngUnsubscribe) 
     .subscribe(
     guides => this.setGuides(guides), 
     error => this.onError(error) 
    ); 
    } 

    ngOnDestroy(): void { 
    this.ngUnsubscribe.next(); 
    this.ngUnsubscribe.complete(); 
    } 

這是服務實現:

@Injectable() 
export class AppService { 

    constructor(private http: Http) { } 

    getGuides(): Observable<Guide[]> { 
    return this.http.get(environment.apiUrl + '/guides') 
     .map(this.extractData); 
    } 

    private extractData(res) { 
    if (res.status < 200 || res.status >= 300) { 
     throw new Error('Bad response status: ' + res.status); 
    } 
    return res.json(); 
    } 
} 

這是失敗的試驗:

class MockAppService extends AbstractMockObservableService { 
    getGuides() { 
    return this; 
    } 
} 
describe('AppComponent',() => { 
    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [AppComponent] 
    }); 

    TestBed.overrideComponent(AppComponent, { 
     set: { 
     providers: [ 
      { provide: AppService, useClass: MockAppService } 
     ] 
     } 
    }); 
    })); 
    it('should render title in a h1 tag', async(() => { 
    const fixture = TestBed.createComponent(AppComponent); 
    fixture.detectChanges(); 
    const compiled = fixture.debugElement.nativeElement; 
    expect(compiled.querySelector('h1').textContent).toContain('app works!'); 
    })); 
+1

post this.appService.getGuides()code? – CharanRoot

+0

我剛剛添加了服務實現以及我在測試中使用的模擬服務,在[this]之後(https://stackoverflow.com/questions/39960146/angular-2-testing-error-case-with-observables在服務/ 39960878#39960878) – Cedric

回答

0

您需要將其導入到您的spec文件中:

import 'rxjs/add/operator/takeUntil'; 
+0

我試過了,但它仍然沒有爲我工作。 – Cedric

+0

您是否嘗試將其添加到組件文件中? – Meir

+0

是的,它在組件和規格文件/ – Cedric

0

getGuides()MockAppService不應返回this,但可觀察到的。

0

試試這個:

class MockAppService extends AbstractMockObservableService { 
    getGuides() { 
    return Observable.of([]); 
    } 
} 

我只是有這個問題我自己。在我來說,我使用的是間諜是這樣的:

spy = spyOn(someService, 'get') 
    .and.returnValue([]); 

我需要什麼做的是這樣做:

spy = spyOn(someService, 'get') 
    .and.returnValue(Observable.of([])); 

沒有爲你的模擬實現,因爲它沒有返回一個可觀察到的不takeUntil方法(不像真正的實施)。