我在Angular 2代码上运行Karma / Jasmine来测试带有模拟后端的http数据服务。我被困在捕获Observable.throw。测试的想法是通过将不可解析的垃圾放入响应主体来触发解析模拟响应的错误,这会触发我正在测试的数据服务中的错误。以下是测试的相关部分。
beforeEach(() => {
this.injector = ReflectiveInjector.resolveAndCreate([
{provide: ConnectionBackend, useClass: MockBackend},
{provide: RequestOptions, useClass: BaseRequestOptions},
Http,
DataQueryService,
]);
this.testDataQueryService = this.injector.get(DataQueryService);
this.backend = this.injector.get(ConnectionBackend) as MockBackend;
this.backend.connections.subscribe((connection: any) => this.lastConnection = connection);
});
...
it( 'Catches Errors' ,
fakeAsync( () => {
var result: any;
var errorResult: any;
//result = null;
let testObject= {testField:'blah blah'};
this.testDataQueryService.getDataFromServer ('//localhost:8080/04_EE_Project/TestServlet',null )
.subscribe( mockParsedResponse => result=mockParsedResponse, error=> this.errorResult = <any>error );
this.lastConnection.mockRespond(new Response
(new ResponseOptions({body: '######' ,
url: '//localhost:8080/04_EE_Project/TestServlet'
})));
tick();
expect(result).toBeUndefined();
expect(errorResult).toBeDefined(); //--- FAILING!!!! :(
} ) );
这是我正在测试的数据查询服务。从调试我知道catch正在激活:
import { Injectable } from '@angular/core';
import { Http, Response, RequestOptionsArgs } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';
@Injectable()
export class DataQueryService {
constructor(private http: Http) { }
getDataFromServer(url: string, requestOptionsArgs: RequestOptionsArgs): Observable<Object> {
return this.http.get(url, requestOptionsArgs).map(this.extractData).catch( error => {
console.log('DataQueryService error thrown: ' + error );
var thrownError = Observable.throw(error )
return thrownError; }) ;
}
private extractData(res: Response) {
var result = {"status": res["status"],"statusText": res["statusText"],"type": res["type"], "headers": res["headers"] ,
"Body": res.json()};
return result || {};
}
}
我花了一些时间进行调试,并且我知道正在触发'catch'并且正在我正在测试的数据服务中定义了“thrownError”(这是为了调试而插入的)。但是,在另一边..
error=> this.errorResult = <any>error
...没有得到错误结果,所以测试失败,因为尽管在测试代码中执行了catch块,但错误没有回到测试中。似乎'subscribe'中的第二个回调旨在填充errorResult不能按预期运行。
如何在此测试中成功捕获错误,因为我的方法不起作用?
答案 0 :(得分:0)
做了一些故障排除并将一个console.log插入到错误处理程序中,结果发现它正在执行。在测试的最后部分省略了“this”关键字导致了这个问题。这是最终确定的测试:
it( 'Catches Errors' ,
fakeAsync( () => {
var result: any;
var errorResult: any;
//result = null;
let testObject= {testField:'blah blah'};
this.testDataQueryService.getDataFromServer ('//localhost:8080/04_EE_Project/TestServlet',null )
.subscribe( mockParsedResponse => result=mockParsedResponse,
(err)=> {console.log('Error has been handled in test 4!: '+ err.message) ; this.errorResult=err ; } );
this.lastConnection.mockRespond(new Response
(new ResponseOptions({body: '######' ,
url: '//localhost:8080/04_EE_Project/TestServlet'
})));
tick();
expect(result).toBeUndefined();
expect(this.errorResult).toBeDefined(); //fixed now, test successful
} ) );
所以事实证明这是为了什么?!
期望(this.errorResult).toBeDefined();
但不是:
期望(结果).toBeUndefined();
...我非常喜欢javascript和“this”关键字我还不完全理解。