我有一个来自nestjs / common的httpService
我正在使用以下内容:
const response = await this.httpService.post(`${this.api}/${action}`, data).toPromise();
和我的jest spec文件中(单元测试)。我正在尝试嘲笑此服务
httpServiceMock = {
post: jest.fn()
};
it('should start', async () => {
const serviceResult = await service.start(data);
});
我遇到了这个错误:
TypeError: this.httpService.post(...).toPromise is not a function
我还试图添加一个承诺结果,例如:
const promise = Promise.resolve('result');
httpServiceMock.post.mockResolvedValue(promise);
也尝试过:
it('should start', async () => {
const mockObservable = Promise.resolve({
toPromise: () => {
console.log('toPromise called');
}
})
httpServiceMock.post.mockImplementation(() => mockObservable);
const serviceResult = await service.start();
});
我的问题是我该如何模仿承诺并返回响应或异常
答案 0 :(得分:0)
返回值httpService.post需要返回一个Observable<AxiosResponse<T>>
,它包含一个属性toPromise,它是一个函数。您的模拟返回一个已解决的诺言,而它需要返回一个假的Observable。
Observable立即返回,因此post
实现只能返回原始值,但是toPromise
需要返回一个Promise。
返回正确的形状对象以消除此错误:
const mockObservable = {
toPromise: () => Promise.resolve('result')
}
httpServiceMock.post.mockImplementation(() => mockObservable);
答案 1 :(得分:0)
我有一个类似的问题,无法通过接受的答案解决。所以我带来了另一个解决方案,以防它可以帮助其他人。
如果您有茉莉花,请使用 jasmine.createSpyObj()
。如果没有,这就是我需要做的:
首先,我实现了一个 jasmine.createSpyObj()
等价物(基于 this answer,稍作修改):
export class TestUtilsService {
static createSpyObj (baseName:string, methodNames:string[]): SpyObject {
let obj: any = {};
for (let i = 0; i < methodNames.length; i++) {
obj[methodNames[i]] = jest.fn();
}
return {[baseName]:()=>obj};
};
}
export class SpyObject {
[key: string]: ()=>{[key:string]:jest.Mock} ;
}
然后我在我的单元测试中使用了它:
const spyHttpClient: SpyObject = TestUtilsService.createSpyObj('get',['toPromise']);
将其添加到测试模块提供程序中:
{provide: HttpClient, useValue: spyHttpClient}
最后,模拟 toPromise 实现以返回模拟响应:
const mockedResponse = {...};
spyHttpClient.get().toPromise.mockImplementationOnce(()=>Promise.resolve(mockedResponse));
await service.myRealMethodThatCallsHttpClient();
expect(service.someUpdatedProp).toBeTruthy();
请注意get方法后面的括号。