Angular 测试 - 使用 rxjs switchMap 的链式 HTTP 请求
Angular Testing - Chained HTTP Requests using rxjs switchMap
我正在尝试在我的服务中对该功能进行单元测试,该服务首先执行 POST 请求,然后再执行 GET。我正在使用 switchMap 来完成此操作,但我遇到的问题是 HttpTestingController 匹配函数
没有接收到这两个请求
这里是我要测试的服务功能:
save(cow: Cow): Observable<Object> {
return this.http.put<Cow>(`${this.cowUrl}/1`, cow, this.httpOptions)
.pipe(switchMap(_ => {
return this.getAllCows();
})
);
}
private getAllCows(): Observable<Cow[]> {
return this.http.get<Cow[]>(`${this.cowUrl}`).pipe(tap(data => {
this.cows = data;
}),
catchError(this.handleError<Cow[]>('getAllCows'))
);
}
这是该函数的规范:
describe('CowService', () => {
let cowService: CowService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
]
});
cowService = TestBed.get(CowService);
httpMock = TestBed.get(HttpTestingController);
});
afterEach(() => {
httpMock.verify();
});
describe('save', () => {
const cowList: Cow[] = [
{ id: '1', name: 'Cow' },
{ id: '2', name: 'Another Cow' }
];
it('Successfully saves cow and updates the list of cows', () => {
const cow: Cow = { id: null, name: 'Third Cow' };
cowService.save(cow).subscribe();
const reqs = httpMock.match(request => request.url = '/api/cows');
console.log(reqs); // shows only the POST request and not the GET
expect(reqs[0].request.url).toEqual('/api/cows');
expect(reqs[0].request.method).toEqual('POST');
expect(reqs[1].request.url).toEqual('/api/cows');
expect(reqs[1].request.method).toEqual('GET');
reqs[0].flush({});
reqs[1].flush(cowList);
});
});
});
执行此操作时出现错误消息:
TypeError: Cannot read property 'flush' of undefined
尝试以下操作:
it('Successfully saves cow and updates the list of cows', () => {
const cow: Cow = { id: null, name: 'Third Cow' };
cowService.save(cow).subscribe(
response => expect(response).toEqual(cowList);
);
const putCall = httpMock.expectOne('/api/cows');
expect(putCall.request.method).toEqual('PUT');
// flush what the put call should return
putCall.flush({});
const getCall = httpMock.expectOne('/api/cows');
expect(getCall.request.method).toEqual('GET');
// flush what the get call should return
getCall.flush(cowList);
});
我正在尝试在我的服务中对该功能进行单元测试,该服务首先执行 POST 请求,然后再执行 GET。我正在使用 switchMap 来完成此操作,但我遇到的问题是 HttpTestingController 匹配函数
没有接收到这两个请求这里是我要测试的服务功能:
save(cow: Cow): Observable<Object> {
return this.http.put<Cow>(`${this.cowUrl}/1`, cow, this.httpOptions)
.pipe(switchMap(_ => {
return this.getAllCows();
})
);
}
private getAllCows(): Observable<Cow[]> {
return this.http.get<Cow[]>(`${this.cowUrl}`).pipe(tap(data => {
this.cows = data;
}),
catchError(this.handleError<Cow[]>('getAllCows'))
);
}
这是该函数的规范:
describe('CowService', () => {
let cowService: CowService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
]
});
cowService = TestBed.get(CowService);
httpMock = TestBed.get(HttpTestingController);
});
afterEach(() => {
httpMock.verify();
});
describe('save', () => {
const cowList: Cow[] = [
{ id: '1', name: 'Cow' },
{ id: '2', name: 'Another Cow' }
];
it('Successfully saves cow and updates the list of cows', () => {
const cow: Cow = { id: null, name: 'Third Cow' };
cowService.save(cow).subscribe();
const reqs = httpMock.match(request => request.url = '/api/cows');
console.log(reqs); // shows only the POST request and not the GET
expect(reqs[0].request.url).toEqual('/api/cows');
expect(reqs[0].request.method).toEqual('POST');
expect(reqs[1].request.url).toEqual('/api/cows');
expect(reqs[1].request.method).toEqual('GET');
reqs[0].flush({});
reqs[1].flush(cowList);
});
});
});
执行此操作时出现错误消息:
TypeError: Cannot read property 'flush' of undefined
尝试以下操作:
it('Successfully saves cow and updates the list of cows', () => {
const cow: Cow = { id: null, name: 'Third Cow' };
cowService.save(cow).subscribe(
response => expect(response).toEqual(cowList);
);
const putCall = httpMock.expectOne('/api/cows');
expect(putCall.request.method).toEqual('PUT');
// flush what the put call should return
putCall.flush({});
const getCall = httpMock.expectOne('/api/cows');
expect(getCall.request.method).toEqual('GET');
// flush what the get call should return
getCall.flush(cowList);
});