Rxjs HttpService的Nest.js处理错误

Rxjs HttpService的Nest.js处理错误,rxjs,axios,nestjs,Rxjs,Axios,Nestjs,我正在尝试测试NestJS基于Axios的内置HttpService。不过,我在测试错误/异常状态时遇到了问题。在我的测试套件中,我有: let client: SomeClearingFirmClient; const mockConfigService = { get: jest.fn((type) => { switch(type) { case 'someApiBaseUrl': { return 'http://exa

我正在尝试测试NestJS基于Axios的内置HttpService。不过,我在测试错误/异常状态时遇到了问题。在我的测试套件中,我有:

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;
  }
无论我使用的是可观察的还是承诺的,我都无法捕捉到任何东西。4xx级别的错误将作为一个成功而继续存在。我觉得我记得Axios添加了一些配置选项,在出现故障时拒绝/向订阅者发送可观察到的错误。。。但我可以想象。我的测试线束是否有问题?我看到的其他StackOverflow帖子似乎说,通过catchError进行管道传输应该可以做到这一点,但我的错误是通过map操作符进行的。

您的mockHttpService似乎没有返回错误,而是返回一个值:

mockHttpService.post=jest.fn=>offailAddAuth; FailAddAuth所做的是发出一个valuefailAddAuth,然后完成

这就是为什么永远不会到达this.httpService.postrl、payload、config中的catchError,因为不会发生错误

为了确保命中catchError,post返回的可观察对象必须发出错误通知

你可以试试这个:

//符合“HttpException”参数的内容 const err={response:'resp',status:'4xx'}; mockHttpService.post=jest.fn=>throwererr; ThrowerError与new Observables=>s.errorerr相同。

您的mockHttpService似乎没有返回错误,而是返回一个值:

mockHttpService.post=jest.fn=>offailAddAuth; FailAddAuth所做的是发出一个valuefailAddAuth,然后完成

这就是为什么永远不会到达this.httpService.postrl、payload、config中的catchError,因为不会发生错误

为了确保命中catchError,post返回的可观察对象必须发出错误通知

你可以试试这个:

//符合“HttpException”参数的内容 const err={response:'resp',status:'4xx'}; mockHttpService.post=jest.fn=>throwererr;
投掷错误与新观测值相同=>s.error.

Ok,这是有道理的。这个问题本身就存在。谢谢好的,这是有道理的。这个问题本身就存在。谢谢