Как выполнить модульное тестирование Nest Js http запроса с полным покрытием? - PullRequest
0 голосов
/ 29 апреля 2020

У меня проблемы с тестированием моего сервиса Nest Js. Я написал метод, который выполняет HTTP-запрос GET:

getEntries(): Observable<Entries[]> {
    Logger.log(`requesting GET: ${this.apiHost}${HREF.entries}`);
    return this.http.get(`${this.apiHost}${HREF.entries}`).pipe(
      catchError((error) => {
        return throwError(error);
      }),
      map(response => response.data)
    );
  }

Я хочу написать модульный тест для этого метода. Этот модульный тест должен охватывать все строки этого метода. Я пытался использовать пакет «nock» для насмешки этого http-запроса, но как бы я ни старался, результат покрытия всегда один и тот же.

return throwError(error);

map(response => response.data);

Эти две строки были раскрыты.

Здесь мой тестовый файл:

describe('getEntries method', () => {
    it('should do get request and return entries', () => {
      nock('http://localhost:3000')
        .get('/v1/entries')
        .reply(200, {
          data: require('../mocks/entries.json')
        });
      try {
        const result = service.getEntries();
        result.subscribe(res => {
          expect(res).toEqual(require('../mocks/entries.json'));
        });
      } catch (e) {
        expect(e).toBeUndefined();
      }
    });
    it('should return error if request failed', () => {
      nock('http://localhost:3000')
        .get('/v1/entries')
        .replyWithError('request failed');
      service.getEntries().subscribe(res => {
        expect(res).toBeUndefined();
      }, err => {
        expect(err).toBe('request failed');
      })
    });
  });

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020

Спасибо за ваш ответ. Код работает принципиально. Мне пришлось сделать несколько изменений, чтобы тест работал. Вот мои изменения:

describe('getEntries method', () => {
    it('should do get request and return entries', (done) => {
      jest.spyOn(service['http'], 'get').mockReturnValue(of({data: require('../mocks/entries.json'), status: 200, statusText: 'OK', headers: {}, config: {}}));
      let data = {};

      service.getEntries().subscribe({
        next: (val) => {data = val},
        error: (err) => { throw err; },
        complete: () => {
          expect(data).toEqual(require('../mocks/entries.json'))
          done();
        }
      });
    });
    it('should return error if request failed', (done) => {
      jest.spyOn(service['http'], 'get').mockReturnValue(throwError('request failed'));
      let data = {};

      service.getEntries().subscribe({
        next: (val) => {data = val},
        error: (err) => {
          expect(err).toBe('request failed');
          done();
        },
        complete: () => {
          expect(data).toBeUndefined();
          done();
        }
      });
    });
  });

Вы должны смоделировать AxiosReponse на httpSpy mockReturnValue, поэтому я добавил «status», «statusText», «header», «config». В противном случае вы получите ошибку типа.

И вторая часть. Я шпионил за httpService так:

let httpService: HttpService;
httpService = module.get(HttpService)

Это не работает. Я должен следить за внедрением HttpService моего Сервиса.

constructor(private readonly http: HttpService) {}

Вот почему мой шпион выглядит так: service ['http'].

Теперь у меня есть полный охват этого http request:)

Спасибо большое;) Хорошего дня!

0 голосов
/ 29 апреля 2020

Я не использовал nock в прошлом, но вы можете просто указать HttpService, что отвечать при использовании jest.spyOn. Самое важное, что нужно помнить, это то, что возвращение является «синхронным», потому что это возвращение наблюдаемого Для проверки вашего положительного случая вы можете сделать что-то вроде

it('should do the request and get the entries', (done) => {
  const httpSpy = jest.spyOn(httpService, 'get')
    .mockReturnValue(of({data: require('../mocks/entries.json')}))
  let data = {};
  service.getEntires().subscribe({
    next: (val) => {data = val},
    error: (err) => { throw error; }
    complete: () => {
      expect(data).toEqual(require('../mocks/entries.json'))
      done();
    }
});

И аналогично, для маршрута ошибки вы можете использовать оператор throwError().

Оба * of и throwError импортированы из rxjs. Единственное, на что следует обратить внимание, так это то, что при использовании этого метода вам нужно получить HttpService из текущего контекста модуля, аналогично тому, как вы получите любую другую службу. Просто убедись, что это произнесено.

...