我正在尝试测试 NestJS 内置的 HttpService(基于 Axios)。不过,我在测试错误/异常状态时遇到了麻烦。在我的测试套件中,我有:
let client: SomeClearingFirmClient;
const mockConfigService = {
get: jest.fn((type) => {
switch(type) {
case 'someApiBaseUrl': {
return 'http://example.com'
}
case 'someAddAccountEndpoint': {
return '/ClientAccounts/Add';
}
case 'someApiKey': {
return 'some-api-key';
}
default:
return 'test';
}
}),
};
const successfulAdd: AxiosResponse = {
data: {
batchNo: '39cba402-bfa9-424c-b265-1c98204df7ea',
warning: '',
},
status: 200,
statusText: 'OK',
headers: {},
config: {},
};
const failAddAuth: AxiosError = {
code: '401',
config: {},
name: '',
message: 'Not Authorized',
}
const mockHttpService = {
post: jest.fn(),
get: jest.fn(),
}
it('Handles a failure', async () => {
expect.assertions(1);
mockHttpService.post = jest.fn(() => of(failAddAuth));
const module: TestingModule = await Test.createTestingModule({
providers: [
{
provide: ConfigService,
useValue: mockConfigService,
},
{
provide: HttpService,
useValue: mockHttpService,
},
SomeClearingFirmClient,
],
}).compile();
client = module.get<SomeClearingFirmClient>(SomeClearingFirmClient);
const payload = new SomeClearingPayload();
try {
await client.addAccount(payload);
} catch(e) {
console.log('e', e);
}
});
我的实现是:
async addAccount(payload: any): Promise<SomeAddResponse> {
const addAccountEndpoint = this.configService.get('api.someAddAccountEndpoint');
const url = `${this.baseUrl}${addAccountEndpoint}?apiKey=${this.apiKey}`;
const config = {
headers: {
'Content-Type': 'application/json',
}
};
const response = this.httpService.post(url, payload, config)
.pipe(
map(res => {
return res.data;
}),
catchError(e => {
throw new HttpException(e.response.data, e.response.status);
}),
).toPromise().catch(e => {
throw new HttpException(e.message, e.code);
});
return response;
}
无论我使用 Observables 还是 Promises,我都无法捕捉到任何东西。 4xx 级错误成功通过。我觉得我记得 Axios 添加了某种配置选项来拒绝/向失败的订阅者发送 Observable 错误......但我可以想象这一点。我在测试工具中做错了吗?我见过的其他 StackOverflow 帖子似乎说通过 catchError
管道应该可以解决问题,但我的错误是通过 map
运算符。
最佳答案
您的mockHttpService
似乎没有返回错误,但返回了一个值:
mockHttpService.post = jest.fn(() => of(failAddAuth));
of(failAddAuth)
所做的是发出一个值 (failAddAuth
) 然后完成。
这就是为什么永远不会到达 this.httpService.post(url, payload, config)
中的 catchError
,因为没有错误发生。
为了确保 catchError
被命中,post()
返回的 observable 必须发出一个错误通知。
你可以试试这个:
// Something to comply with `HttpException`'s arguments
const err = { response: 'resp', status: '4xx' };
mockHttpService.post = jest.fn(() => throwError(err));
throwError(err)
与 new Observable(s => s.error(err))
( Source code ) 相同。
关于rxjs - Nest.js 处理 HttpService 的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61742615/