2017-06-19 36 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方法(不像真正的实施)。