2017-09-05 3 views
0

Ich bleibe stecken und bekomme immer Fehler beim Testen einer Angular 4 Komponente.Angular 4 Einheit Testfehler "TypeError: Kann Eigenschaft 'subscribe' von undefined nicht lesen"

Hier ist meine Komponente:

auftrags detail.component.ts

@Component({ 
    selector: 'order-detail', 
    templateUrl: 'order-detail.component.html', 
    providers: [OrderService] 
}) 
export class OrderDetailComponent implements OnInit { 
    private order: Order; 

    constructor(
    private orderService: OrderService, 
    private route: ActivatedRoute, 
    private router: Router 
) {} 

    ngOnInit() { 
    this.getOrder(); 
    } 

    private getOrder(): void { 
    this.route.paramMap 
     .map((params: ParamMap) => { 
     if (+params.get('id') === 0) { 
      this.router.navigateByUrl('/404', {skipLocationChange: true}); 
     } 

     return params; 
     }) 
     .switchMap((params: ParamMap) => this.orderService.getOrder(+params.get('id'))) 
     .subscribe((order: Order) => this.order = order); 
    } 
} 

Und hier ist ein Service:

order.service.ts

@Injectable() 
export class OrderService { 
    private ordersUrl = `${environment.apiUrl}/orders/`; 

    constructor(private http: HttpClient) {} 

    getOrder(id: number): Observable<Order> { 
    return this.http.get(`${this.ordersUrl}${id}/`) 
     .map(response => response as Order); 
    } 
} 

Und ich will einen Spion auf OrderServive und Einheit setzen es mit einem solchen Test testen:

auftrags detail.component.spec.ts

describe('Order detail component',() => { 
    let fixture: ComponentFixture<OrderDetailComponent>; 
    let page: Page; 
    let activatedRoute: ActivatedRouteStub; 
    const fakeOrder: Order = { 
    id: 1, 
    title: 'Test 1', 
    contractor: {title: 'Contractor 1'} as Contractor, 
    } as Order; 

    class Page { 
    orderSpy: jasmine.Spy; 
    routerSpy: jasmine.Spy; 
    title: HTMLElement; 

    constructor() { 
     const orderService = fixture.debugElement.injector.get(OrderService); 
     this.orderSpy = spyOn(orderService, 'getOrder').and.returnValue(Observable.of(fakeOrder)); 
    } 
    } 

    function createComponent() { 
    fixture = TestBed.createComponent(OrderDetailComponent); 
    page = new Page(); 

    fixture.detectChanges(); 

    return fixture.whenStable().then(() => { 
     fixture.detectChanges(); 
    }); 
    } 

    beforeEach(() => { 
    activatedRoute = new ActivatedRouteStub(); 
    }); 

    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [OrderDetailComponent], 
     imports: [RouterTestingModule, HttpClientTestingModule], 
     providers: [ 
     OrderService, 
     {provide: ActivatedRoute, useValue: activatedRoute}, 
     {provide: Router, useClass: RouterStub}, 
     ], 
     schemas: [NO_ERRORS_SCHEMA], 
    }).compileComponents(); 
    })); 

    describe('when navigate with existing id',() => { 
    beforeEach(async(() => { 
     activatedRoute.testParamMap = {id: fakeOrder.id}; 
     createComponent(); 
    })); 

    it('should show title',() => { 
     expect(page.orderSpy).toHaveBeenCalledWith(fakeOrder.id); 
    }); 
    }); 

}); 

Aber ich erhalte immer diese Fehlermeldung: TypeError: Cannot read property 'subscribe' of undefined

nahm ich ActivatedRouteStub und Teststruktur aus Agular Dokumentation: https://angular.io/guide/testing

Bauteile Code arbeitet mit realen Daten aus Backend-Fein und zeigt mir Ordnung.

Auch meine Codebasis enthält ähnliche Test, die erfolgreich das gleiche auf einer anderen Komponente mit ähnlichem Dienst tut, so ist dieser Test der einzige Ort, der fehlschlägt.

Mit Angular 4.3.6, Karma 1.7.1 und Jasmin 2.6.4.

Was könnte schief gehen und wie kann man diesen Fehler loswerden?

Antwort

1

Nach ein paar Recherchen habe ich herausgefunden, was den Fehler verursacht hat. Ich entfernte

{provide: Router, useClass: RouterStub}, 

und der Fehler war weg. Test funktioniert jetzt perfekt ohne diesen Stub.

Nicht sicher, was das Problem war, aber ich nehme an, dass RouterStub Klasse von Docs fehlt die Implementierung einiger notwendiger Dinge. Klasse wurde von hier genommen:

https://angular.io/guide/testing#test-a-routed-component

https://angular.io/generated/live-examples/testing/app-specs.eplnkr.html

Verwandte Themen