NestJS+jestのテストでHTTP通信部分をモックする


NestJSで実装したコントローラで、HttpServiceを使ってHTTP通信をしている処理があったのだが、テストを書く際にHTTP通信部分をどうにかする必要があった。
Dockerでローカルにサーバーを立てることも考えたが、jestでモックできたのでメモとして残しておく。

import { HttpService, INestApplication } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { AxiosResponse } from 'axios';
import { of } from 'rxjs';
import * as request from 'supertest';

describe('controller test', () => {
  let app: INestApplication;
  let module: TestingModule;
  let httpService: HttpService;

  describe('hoge endpoint', () => {
    beforeAll(async () => {
      module = await Test.createTestingModule({}).compile();

      app = module.createNestApplication();
      await app.init();

      httpService = module.get<HttpService>(HttpService);
    });
    afterAll(async () => {
      await app.close();
      await module.close();
    });

    it('hoge', async () => {
      const params = {
        hoge: 'hoge',
        fuga: 'fuga',
      };

      const generatePostRequest = () =>
        request(app.getHttpServer())
          .post('/hoge/endpoint');

      jest.spyOn(httpService, 'post').mockImplementationOnce(() =>
        of({
          data: {
            hoge: '1',
            fuga: 2,
          },
        } as AxiosResponse),
      );

      await generatePostRequest()
        .send(params)
        .then((response: any) => {
          expect(response.body.success).toBe(1);
          expect(response.body.data).toBeTruthy();
        });
    });
  });
});

mockImplementationOnceで期待している戻り値を返却するようにモックすればOK.