2017-07-26 5 views
3

Ich erkunde das neue Angular HttpClientModule und stolperte in einen unerklärlichen Fehler. Das Modul ist neu genug, dass ich noch keine brauchbaren Informationen zum Komponententest finden kann, und die offizielle Dokumentation enthält keine Beispiele.Fehler beim Komponententest HttpClientModule (Angular 4.3+)

Die App enthält einen Dienst mit einer Methode, die eine URL an http.get übergibt. Wenn ich diese Methode in einem Browser-Kontext (alias ng serve) aufrufen, wird der http-Aufruf normal ausgeführt. Wenn im Rahmen eines Unit-Test genannt, bekomme ich folgende Fehlermeldung:

TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Dies ist ein minimal-App ist mit kantigem CLI erzeugt. Hier ist der relevante Code:

app.module.ts:

import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule } from '@angular/core'; 
import { HttpClientModule } from '@angular/common/http'; 
import { AppComponent } from './app.component'; 

@NgModule({ 
    declarations: [AppComponent], 
    imports: [BrowserModule, HttpClientModule], 
    providers: [], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { } 

app.component.ts:

import { Component, OnInit } from '@angular/core'; 
import { TestService } from './test.service' 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'], 
    providers: [TestService] 
}) 
export class AppComponent { 
    title = 'app'; 

    constructor(private testSvc: TestService) {} 

    ngOnInit() { 
    this.testSvc.executeGet('http://www.example.com'); 
    } 
} 

test.service.ts:

import { Injectable } from '@angular/core'; 
import { HttpClient } from '@angular/common/http'; 

@Injectable() 
export class TestService { 
    constructor(private http:HttpClient) {} 

    executeGet(url:string) { 
    this.http.get(url) 
     .subscribe(
     data => console.log('success', data), 
     error => console.log('error', error) 
    ); 
    } 
} 

test.service.spec.ts:

import { HttpClient, HttpHandler } from '@angular/common/http'; 
import { TestBed, inject } from '@angular/core/testing'; 
import { TestService } from './test.service'; 

describe('TestService',() => { 
    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     providers: [HttpClient, HttpHandler, TestService] 
    }); 
    }); 

    it('should executeGet', inject([TestService], (svc: TestService) => { 
    expect(svc.executeGet).toBeDefined(); 
    // this is where the 'undefined' error occurs 
    svc.executeGet('http://www.example.com'); 
    })); 
}); 

Jede mögliche Anleitung oder Zeiger sehr geschätzt.

+0

Sie wirklich eine echte HttpClientModule brauchen? Laut [Dokumentation] (https://angular.io/guide/http#testing-http-requests) - das HTTP-Backend muss als Teil einer guten Testpraxis verspottet werden. –

+0

@AleksandrPetrovskij Ich habe die verfügbare Dokumentation gelesen. Es ist ziemlich dünn und HttpClientModule ist jung genug, dass es nicht viele Inhalte von Drittanbietern gibt, wie man es benutzt. Beim Versuch, HttpClientTestingModule zu verwenden, habe ich andere Probleme festgestellt, aber ich habe mich entschieden, sie nicht in diesen Beitrag aufzunehmen, um den Fokus auf den Fehler 'undefiniert' zu legen. Egal, –

Antwort

1

Import von HttpClientModule fehlt

Here is the working example on plnkr

describe('TestService',() => { 
    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     imports: [HttpClientModule], 
     providers: [TestService] 
    }); 
    }); 

    it('should executeGet',() => { 
    const testService = TestBed.get(TestService); 

    expect(testService.executeGet).toBeDefined(); 
    testService.executeGet('http://www.example.com'); 
    })); 
}); 
+0

Vielen Dank für das Beispiel. Ich schätze es. Das heißt, es hilft mir nicht, den Fehler zu verstehen, und auch nicht, warum es unmöglich zu sein scheint, Unit-Test ohne Mocks. Ich verstehe, warum Spott in Tests eine gute Idee ist, aber nicht warum der HTTP-Aufruf fehlschlägt, wenn keine Mocks vorhanden sind, was der Kern meiner Frage ist. –

+0

Ich denke Import von * HttpClientModule * fehlt, [Beispiel] (http://pnnr.co/edit/InyCCcl74EzzDXGo2owY) –

+0

Das war's! Nochmals vielen Dank, Aleksandr. Wenn Sie Ihre Antwort aktualisieren oder eine andere Nachricht posten möchten, akzeptiere ich sie gerne. –

3

Kürzlich erlebte ich genau das gleiche Problem, bei dem die Fehlermeldung sagt:

TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Für mich ist die Quelle dieser Fehler nicht HttpInterceptor ordnungsgemäß verwendet wurde. Wenn Sie auch benutzerdefinierte HttpInterceptor bieten stellen Sie sicher, dass Sie es richtig verwenden. Im folgenden Codeausschnitt beachten Sie, wie ich Observable, Promise, Array, or Iterable zurückgeben, wenn Fehlerstatus anders als 401 ist. Standardmäßig undefined wird von Observable, Promise, Array, or Iterable anstelle von Observable, Promise, Array, or Iterable zurückgegeben, so eckig beschwert sich darüber.

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
    return next.handle(req).catch(err => { 
     if(err instanceof HttpErrorResponse) { 
     if(err.status === 401) { 
      this.store.dispatch(this.authAction.unauthorized(err)); 
      return Observable.throw(err); 
     } 
     } 
    }) 
    } 

und das Fix zu ist, war folgendes Code-Snippet.

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
    return next.handle(req).catch(err => { 
     if(err instanceof HttpErrorResponse) { 
     if(err.status === 401) { 
      this.store.dispatch(this.authAction.unauthorized(err)); 
     } 
     } 
     return Observable.throw(err); //Actually this line of code 
    }) 
    } 
+0

Ich verwende keine HttpInterceptor. Wie bereits erwähnt, funktioniert 'TestService.executeGet', wenn es in einem Browserkontext ausgeführt wird, aber in einem Komponententest fehlschlägt. Es liegt etwas am Umweltunterschied, der das Problem verursacht. –

+0

Wie testen Sie den Interceptor? Haben Sie eine Probe zum Teilen? – Angad

Verwandte Themen