我正在探索新的Angular HttpClientModule并遇到一个无法解释的错误。该模块足够新,我还无法找到有关如何进行单元测试的任何有用信息,官方文档也没有任何示例。
该应用包含一项服务,该方法将网址传递给http.get
。当我在浏览器上下文(又名ng serve
)中调用此方法时,http调用正常执行。在单元测试的上下文中调用时,我收到以下错误:
TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
这是使用Angular CLI生成的最小应用程序。这是相关的代码:
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');
}));
});
任何指导或指示非常感谢。
答案 0 :(得分:3)
最近我遇到了完全相同的问题,其中包含错误消息:
TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
对我来说,此错误的来源并未正确使用 HttpInterceptor 。如果您还提供自定义 HttpInterceptor ,请确保正确使用它。在以下代码段中,请注意如果错误状态不是401,我错过了返回Observable, Promise, Array, or Iterable
的方式。默认情况下,undefined
方法返回intercept
而不是Observable, Promise, Array, or Iterable
,因此有角度抱怨关于那个。
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);
}
}
})
}
,修复方法是以下代码段。
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
})
}
答案 1 :(得分:1)
导致缺少HttpClientModule
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');
}));
});