【问题标题】:How to test (Jasmine) a service actually handles the error on mocked HTTP error如何测试(Jasmine)服务实际处理模拟 HTTP 错误的错误
【发布时间】:2017-09-30 06:32:01
【问题描述】:

我有一个通过 Swagger 生成的 Angular 服务。

该服务只是进行 HTTP 调用并返回用户列表。我设法为“成功”调用正确编码测试用例。

但是,我很难对“失败”案例进行测试。

我试图简单地调用该函数并通过模拟响应,创建一个“错误”响应,但它似乎无法检测到实际抛出的异常。

您将在下面找到服务和我的测试用例:

service.ts

getListUsers(): Observable<UsersListModel | null> {
    let url_ = this.baseUrl + "/api/users";
    url_ = url_.replace(/[?&]$/, "");

    const content_ = "";

    let options_ = {
        body: content_,
        method: "get",
        headers: new Headers({
            "Content-Type": "application/json; charset=UTF-8", 
            "Accept": "application/json; charset=UTF-8"
        })
    };

    return this.http.request(url_, options_).flatMap((response_) => {
        return this.processGetListUsers(response_);
    }).catch((response_: any) => {
        if (response_ instanceof Response) {
            try {
                return this.processGetListActivities(response_);
            } catch (e) {
                return <Observable<UsersListModel>><any>Observable.throw(e);
            }
        } else
            return <Observable<UsersListModel>><any>Observable.throw(response_);
    });
}

protected processGetListUsers(response: Response): Observable<UsersListModel | null> {
    const status = response.status; 

    if (status === 200) {
        const responseText = response.text();
        let result200: UsersListModel | null = null;
        let resultData200 = responseText === "" ? null : JSON.parse(responseText, this.jsonParseReviver);
        result200 = resultData200 ? UsersListModel.fromJS(resultData200) : <any>null;
        return Observable.of(result200);
    } else if (status !== 200 && status !== 204) {
        const responseText = response.text();
        return throwException("An unexpected server error occurred.", status, responseText);
    }
    return Observable.of<UsersListModel | null>(<any>null);
}

规格文件

describe('ERROR on Get Users List', () => {
    let backend: MockBackend;
    let service: UserService;
    let response: Response;

    beforeEach(async(() => {    
      TestBed.configureTestingModule({
        imports: [HttpModule],
        providers: [
          MockBackend,
          { provide: XHRBackend, useClass: MockBackend },

          UserService
        ]
      });
    }));

    beforeEach(inject([Http, XHRBackend], (http: Http, be: MockBackend) => {
      backend = be;
      service = new UserService(http);
      let options = new ResponseOptions({status: 500, body: 'API Error'});
      response = new Response(options);
    }));

    it('should handle an API error on getListUsers()', async(inject([], () => {
        backend.connections.subscribe((c: MockConnection) => {
          c.mockRespond(response);
        });

        expect(() => service.getListUsers()).toThrowError();
      }))
    );

  });

使用这个测试用例,测试失败,没有更多信息:

预期函数会引发错误。

我什至尝试使用订阅来检测一些东西:

it('should handle an API error on getListUsers()', async(inject([], () => {
    backend.connections.subscribe((c: MockConnection) => {
      c.mockRespond(response);
    });

    spyOn(console, 'error');

    service.getListUsers()
      .subscribe(
      res => {},
      err => { 
        console.error(err)
      });

    expect(console.error).toHaveBeenCalled();
  }))
);

在这里我可以看到控制台中抛出的错误,但永远不会触发 console.error。

所以,也许我的测试用例不合适。

【问题讨论】:

    标签: angular typescript error-handling jasmine karma-jasmine


    【解决方案1】:

    该断言助手无法工作,因为错误被包装并通过 Observable 的错误通知通道传播。

    为此,您需要订阅 observable 并相应地断言

    service.getListActivities().subscribe(
      () => test.failure('expected an error but observable terminated successfully.'),
    
      () => test.success('observable threw an error as expected.')
    );
    

    该示例被概括为您调用的特定助手将取决于所使用的测试框架。

    【讨论】:

    • 您好!谢谢你。如我的问题所述,我尝试了这种方法。我使用 Jasmine,但我无法测试我的 observable 是否真的抛出了错误。
    • 我认为对于 Jasmine,您需要在错误处理程序中调用 done
    • 我仍然很难让它发挥作用。 done 方法似乎不适应。我将深入研究文档。
    猜你喜欢
    • 2019-02-12
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2015-03-08
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    相关资源
    最近更新 更多