如何在服务调用中对 mergeMap 进行单元测试
How to unit test mergeMap in service call
我想对包含使用 mergeMap 调用两个 API 的方法的服务进行单元测试。
我已经编写了测试用例,但它只通过了第一个 API 调用。我无法弄清楚这如何适用于 API 调用。
这是我的 posts.service.ts
:
getRequest():Observable<any>{
return this.httpClient.get<any>(`https://some-api/v1/get`).pipe(
mergeMap(token=>this.httpClient.get<optout>(`https://another-api/v2/get`))
)
}
这是我试过的 posts.service.spec.ts
文件:
describe('PostsService', () => {
let service: postsService;
let httpController: HttpTestingController;
let apiURL=environment.apiURL;
let getTokenApi='http://https://some-api/v1/get';
let getProductApi='https://another-api/v2/get';
beforeEach(() => {
TestBed.configureTestingModule({
imports:[HttpClientTestingModule,HttpClientModule],
providers:[{provide:API_CONFIG_TOKEN,useValue:{usewsfApi:false}},postsService]
});
service = TestBed.get(postsService);
httpController=TestBed.get(HttpTestingController);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should retrieve the products and token from API via GET', () => {
const postsMock:optout={
"productsample": [
{
"privacyType": "val1",
"consented": false,
},{
"privacyType": "val2",
"consented": false,
},{
"privacyType": "val3",
"consented": true,
}
]
}
service.getRequest().subscribe(posts=>{
expect(posts).toEqual(postsMock);
})
const req=httpController.expectOne({
method:'GET',
url:getTokenApi
});
req.flush(postsMock);
});
});
在继续测试 mergeMap
内的调用之前,您需要修复以下导致单元测试 运行 错误的代码:
it('should retrieve the products and token from API via GET', () => {
同步测试 运行,但是以下 expect
调用是 运行 异步:
service.getRequest().subscribe(posts=>{
expect(posts).toEqual(postsMock);
})
这意味着单元测试不会等待异步代码完成 运行ning 并断定测试已经完成,而没有给这些 expect
调用机会 运行 .此外,他们有可能永远不会 运行 开头。
我建议将单元测试参数更改为 (done) => {
,然后在 expect
之后添加 done
回调,如下所示:
service.getRequest().subscribe(posts=>{
expect(posts).toEqual(postsMock);
done();
})
完成上述操作后,您需要做的就是使用适当的 return 货物重复 getProductApi
调用的 flush
实现。
这应该会调用 service.getRequest().subscribe(
调用,您应该能够断言结果。但是,我可以看到您当前期望的结果是 postsMock
,考虑到您正在测试的实际代码是不正确的,因为它应该是 mergeMap
.
的结果
希望这能引导您走向正确的道路!
我想对包含使用 mergeMap 调用两个 API 的方法的服务进行单元测试。 我已经编写了测试用例,但它只通过了第一个 API 调用。我无法弄清楚这如何适用于 API 调用。
这是我的 posts.service.ts
:
getRequest():Observable<any>{
return this.httpClient.get<any>(`https://some-api/v1/get`).pipe(
mergeMap(token=>this.httpClient.get<optout>(`https://another-api/v2/get`))
)
}
这是我试过的 posts.service.spec.ts
文件:
describe('PostsService', () => {
let service: postsService;
let httpController: HttpTestingController;
let apiURL=environment.apiURL;
let getTokenApi='http://https://some-api/v1/get';
let getProductApi='https://another-api/v2/get';
beforeEach(() => {
TestBed.configureTestingModule({
imports:[HttpClientTestingModule,HttpClientModule],
providers:[{provide:API_CONFIG_TOKEN,useValue:{usewsfApi:false}},postsService]
});
service = TestBed.get(postsService);
httpController=TestBed.get(HttpTestingController);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should retrieve the products and token from API via GET', () => {
const postsMock:optout={
"productsample": [
{
"privacyType": "val1",
"consented": false,
},{
"privacyType": "val2",
"consented": false,
},{
"privacyType": "val3",
"consented": true,
}
]
}
service.getRequest().subscribe(posts=>{
expect(posts).toEqual(postsMock);
})
const req=httpController.expectOne({
method:'GET',
url:getTokenApi
});
req.flush(postsMock);
});
});
在继续测试 mergeMap
内的调用之前,您需要修复以下导致单元测试 运行 错误的代码:
it('should retrieve the products and token from API via GET', () => {
同步测试 运行,但是以下 expect
调用是 运行 异步:
service.getRequest().subscribe(posts=>{
expect(posts).toEqual(postsMock);
})
这意味着单元测试不会等待异步代码完成 运行ning 并断定测试已经完成,而没有给这些 expect
调用机会 运行 .此外,他们有可能永远不会 运行 开头。
我建议将单元测试参数更改为 (done) => {
,然后在 expect
之后添加 done
回调,如下所示:
service.getRequest().subscribe(posts=>{
expect(posts).toEqual(postsMock);
done();
})
完成上述操作后,您需要做的就是使用适当的 return 货物重复 getProductApi
调用的 flush
实现。
这应该会调用 service.getRequest().subscribe(
调用,您应该能够断言结果。但是,我可以看到您当前期望的结果是 postsMock
,考虑到您正在测试的实际代码是不正确的,因为它应该是 mergeMap
.
希望这能引导您走向正确的道路!