我有一个数据服务,它从服务器获取数据并生成多个请求,然后返回一个可观察数组.我想测试数据.
我尝试做的是在我发送的mockrespone数组中包含两个observables我不知道这是否是测试数据的正确方法.
但是测试失败了,尤其是异步测试块中的最后三个测试
重要提示:我想测试一下,当将charId设置为falsy并将comicsId设置为falsy时,调用方法,订阅它返回的observable,在你模拟了http后,你会得到一个包含两个预期响应的数组.如果charId是真实的,则与预期的4个响应相同.当comicsId真实时,6个预期的回应也是如此
//获取数据的服务
getChar(): Observable<any> { const Observables = []; Observables.push(this.http.get('https://gateway.marvel.com:443/v1/public/characters?apikey')); Observables.push(this.http.get('https://gateway.marvel.com:443/v1/public/comics?apikey')); if (this.charId) { Observables.push(this.http.get(`${this.urlChar}${this.charId}${this.apiKey}`)); Observables.push(this.http.get(`${this.urlChar}${this.charId}/comics${this.apiKey}`)); } if (this.comicsId) { Observables.push(this.http.get(`${this.urlCom}${this.comicsId}${this.apiKey}`)); Observables.push(this.http.get(`${this.urlCom}${this.comicsId}/creators${this.apiKey}`)); } console.log([Observable,Observable]); return Observable.forkJoin(Observables); } }
//我的考试
import { async,ComponentFixture,TestBed,getTestBed,inject } from '@angular/core/testing'; import { MockBackend,MockConnection } from '@angular/http/testing'; import { DataService } from './data.service'; import { BaseRequestOptions,Http,XHRBackend,HttpModule,Response,ResponSEOptions,RequestMethod } from '@angular/http'; import { Observable } from 'rxjs/Observable'; describe('DataService',() => { let mockBackend: MockBackend; beforeEach(async(() => { TestBed.configureTestingModule({ providers: [ DataService,MockBackend,BaseRequestOptions,{ provide: Http,deps: [MockBackend,BaseRequestOptions],useFactory: (backend: XHRBackend,defaultOptions: BaseRequestOptions) => { return new Http(backend,defaultOptions); } } ],imports: [ HttpModule ] }); mockBackend = getTestBed().get(MockBackend); })); it('should get ObservableArr',(done) => { let dataService: DataService; getTestBed().compileComponents().then(() => { mockBackend.connections.subscribe( (connection: MockConnection) => { connection.mockRespond(new Response( new ResponSEOptions({ body: [Observable,Observable] } ))); }); dataService = getTestBed().get(DataService); expect(DataService).toBeDefined(); dataService.getChar().subscribe((obsArr: Observable<any>[]) => { expect(obsArr.length).toBeDefined(); expect(obsArr.length).toEqual(2); expect(obsArr.length).not.toBe(1); done(); }); }); }); it('should check the service',inject([DataService],(service: DataService) => { expect(service).toBeTruthy(); })); it('should get ObservableArray async',async(inject([DataService],(dataService: DataService) => { mockBackend.connections.subscribe( (connection: MockConnection) => { connection.mockRespond(new Response( new ResponSEOptions({ body: [Observable,Observable] } ))); }); dataService.getChar().subscribe( (response) => { expect(response.length).toBe(2); expect(response[0]).toBe(Observable); <<<<<<<<<<<<<< Fails expect(response[1]).toBe(Observable); <<<<<<<<<<<<<< Fails expect(response).toEqual([Observable,Observable]); <<<<<< Fails }); }))); });
首先,正如@Aviad P.指出的那样,forkJoin方法不返回一个Observable的Observable数组……它返回一个forkJoin中每个observable结果的数组,并且该observable的结果不是Observables实例.
此外,你没有嘲笑getChart()方法,模拟后端你正在模拟每个http调用,但不是方法getChar()本身.数组必须是=== 2的长度,因为不存在this.chartId和this.comicsId ……
所以我会说返回的结构是这样的,所以response [0]是一个数组:
response = [[Observable,Observable],[Observable,Observable]]
说,这种期望永远不会成真,因为没有一个数组等于创建的新数组:
expect(response).toEqual([Observable,Observable])
修改所有应解决问题的方法.另外,如果你的Observables返回了Observable实例,你的代码:’body:[Observable,Observable]’没有返回Observables实例,它返回Observable定义函数,这将是一个不正确的mock,虽然测试会通过.
这将是一个失败的测试示例:
const mockResponse = {isMockResponse: true}; it('should get ObservableArray async',(dataService: DataService) => { mockBackend.connections.subscribe( (connection: MockConnection) => { connection.mockRespond(new Response( new ResponSEOptions({ body: {...mockResponse} } ))); }); dataService.getChar().subscribe( (response) => { expect(response.length).toBe(2); expect(response[0].isMockResponse).toBe(true); <<< Is this expect really necessary? expect(response[1].isMockResponse).toBe(true); <<< Is this expect really necessary? }); })));
说,唯一的期望是测试你的用例是这样的:
expect(response.length).toBe(2);
其他的是不必要的…所以你没有测试你正在嘲笑的数据,你想测试由于变量this.chartId和this.comicsIs的值而执行的调用次数.
希望这可以帮助.