【问题标题】:How to unit test NestJs http request with full coverage?如何对完整覆盖的 NestJs http 请求进行单元测试?
【发布时间】:2020-08-13 10:45:20
【问题描述】:

我无法测试我的 NestJs 服务。我写了一个方法,它执行 GET http 请求:

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');
      })
    });
  });

【问题讨论】:

    标签: typescript unit-testing jestjs nestjs


    【解决方案1】:

    我过去没有使用过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() 运算符。

    ofthrowError 都是从 rxjs 导入的。唯一需要注意的是,使用此方法,您确实需要从当前模块上下文中获取 HttpService,类似于获取任何其他服务的方式。只是确保把它说出来。

    【讨论】:

    • 感谢您,我发布了一些更改。
    • post 有什么办法吗?
    • jest.spyOn(httpService, 'post')... 大部分都如您所愿。这只是HttpService上的另一种方法@
    【解决方案2】:

    感谢您的回复。该代码从根本上起作用。我必须进行一些更改才能使测试正常工作。这是我的更改:

    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();
            }
          });
        });
      });
    

    你必须在 httpSpy mockReturnValue 上模拟 AxiosReponse,所以我添加了 'status'、'statusText'、'header'、'config'。否则会出现类型错误。

    还有第二部分。我像这样监视 httpService:

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

    这不起作用。我必须监视我的 Service 的 HttpService 注入。

    constructor(private readonly http: HttpService) {}
    

    这就是为什么我的间谍看起来像:service['http']。

    现在我已经完全覆盖了这个 http 请求 :)

    非常感谢;) 祝你有美好的一天!

    【讨论】:

      猜你喜欢
      • 2018-03-13
      • 2023-03-20
      • 2020-07-06
      • 2016-05-04
      • 2022-01-26
      • 1970-01-01
      • 2013-07-08
      • 2011-03-14
      • 1970-01-01
      相关资源
      最近更新 更多