expect()。toThrow()在运行测试时不起作用

时间:2017-10-26 13:46:05

标签: angular unit-testing

我对Angular4中的服务进行了以下测试:

it('should throw an error when given an invalid Batch ID',
    async(inject([EventLogService, HttpTestingController],
      (service: EventLogService, backend: HttpTestingController) => {
        const batchId = "nope";

        expect(function() {
          service.getEvents(batchId).subscribe();
        }).toThrow();

        backend
          .expectOne(service.createUrl(EVENTS_URL, batchId, EVENTS_ENDPOINT));
      }))
);

expect().toThrow()即使我运行应用并给它batchId "nope",也无法正常工作,但会出现错误。换句话说,即使测试失败,测试也会通过。

这就是服务功能的样子:

public getEvents(batchId: string): Observable<EventLogModel[]> {
    let url = this.createUrl(EVENTS_URL, batchId, EVENTS_ENDPOINT);

    return this.httpClient.get(url)
      .map((res: any) => {
        const events = res.eventList;
        return events.map((e) => new EventLogModel(e));
      })
      .catch(this.handleError);
}

private handleError(error: Response | any) {
  console.error(error.message || error);
  return Observable.throw(error.message || error);
}

我做错了什么?

修改

我尝试了以下内容:

  it('should throw an error when given an invalid Batch ID',
    fakeAsync(inject([EventLogService, HttpTestingController],
      async (service: EventLogService, backend: HttpTestingController) => {
        const batchId = "nope";

        const err =
          await service.getEvents(batchId).toPromise()
            .then(() => { throw new Error('Unexpected') })
            .catch(err => err);

        expect(err).toEqual(jasmine.any(Error));

        //Expected no open requests, found one ERROR
        backend
          .expectOne(service.createUrl(EVENTS_URL, batchId, EVENTS_ENDPOINT));
      }))
  );

但即使我明确说Error: Expected no open requests, found 1,也要让测试失败说.expectOne()

2 个答案:

答案 0 :(得分:1)

这是因为toThrow需要一个会抛出错误的函数。虽然service.getEvents返回一个可观察到的错误,但应该进行相应的测试。例如,可以将observable转换为promise并使用async..await进行测试:

it('should throw an error when given an invalid Batch ID',
    fakeAsync(inject([EventLogService, HttpTestingController],
      async (service: EventLogService, backend: HttpTestingController) => {
        ...
        const err = await service.getEvents(batchId).toPromise()
        .then(() => { throw new Error('Unexpected') })
        .catch(err => err);

        expect(err).toEqual(jasmine.any(Error));
        ...
      }))
);

由于规范模拟了请求,因此可以安全地将其从async更改为fakeAsync

答案 1 :(得分:0)

这篇文章解释了toThrow()失败,因为它试图调用该方法。

https://ajsblackbelt.wordpress.com/2014/05/18/jasmine-tests-expect-tothrow/comment-page-1/

作者继续详细解释这一点。他们建议您可以写一下:expect(service.method).toThrow()

这对我有用,因为我的方法没有参数。对于带参数的方法,我建议阅读详细信息的帖子。