什么是测试返回http observables的方法的正确方法?

时间:2019-02-09 17:03:09

标签: javascript typescript jasmine rxjs karma-jasmine

我有一个TypeScript项目,我想将其部署为JS NPM软件包。该软件包使用rxjs ajax函数执行一些http请求。现在,我想为这些方法编写测试。

在某种程度上,我有一个这样的方法(简化!):

getAllUsers(): Observable<AjaxResponse> {
    return ajax.get(this.apiUrl + '/users');
}

我了解基本测试,例如使用spyOn可以模拟服务器的响应。但是我将如何实际测试http请求?

茉莉花的文档说我不能在it部分进行异步工作,但是可以在beforeEach中进行https://jasmine.github.io/tutorials/async

这是测试API的正确方法吗?

let value: AjaxResponse;
let error: AjaxError;

beforeEach((done) => {

    const user = new UsersApi();
    user.getAllUsers().subscribe(
        (_value: any) => {
            value = _value;
            done();
        },
        (_error: any) => {
            error = _error;
            done();
        }
    );

});

it("should test the actual http request", () => {

    // Test here something
    // expect(value).toBe...
    // expect(error).toBe...

});

我想不出另一种方法如何进行异步工作...

1 个答案:

答案 0 :(得分:2)

您需要模拟ajax.get以返回一个Observable,该Observable发出要测试的值。

完成此操作取决于您在包含ajax方法的文件中如何声明user.getAllUsers

最好将UsersApi()传递给ajax(纯函数样式),因为那样的话,您可以做这样的事情:

例如

class UsersApi {

    public ajax;

    constructor(ajax) {
      this.ajax = ajax;
    }

    getAllUsers() {
      return this.ajax.get(....)
    }

}

编辑:传递依赖项(也称为依赖项注入)是使这样的模块易于测试的一件事-考虑这样做!

然后,您可以很容易地像这样模拟测试:

  const someSuccessfulResponse = ...
  const someFailedResponse = ...

  const ajaxWithSuccess = {
     get:jest.fn(() => of(someSuccessfulResponse))
  }

  const ajaxWithFailed = {
     get:jest.fn(() => throwError(someFailedResponse))
  }

  describe('my test suite',() => {

    it("should test a successful response", (done) => {

        const user = new UsersApi(ajaxWithSuccess);
        user.getAllUsers().subscribe(d => {
         expect(d).toBe(someSuccessfulResponse);
         done();
       });

    });

    it("should test a failed response", (done) => {

        const user = new UsersApi(ajaxWithFailed);
        user.getAllUsers().subscribe(null,error => {
         expect(d).toBe(someFailedResponse);
         done();
       });

    });

  });

注意:您不要要测试实际的API请求。 您想测试您的代码是否能够成功处理您认为可以收到的所有API响应。考虑一下,如果您的API始终会正确处理失败的API响应,那么您将如何测试该代码是否正确处理了返回200s?

编辑#27:上面的代码在我开玩笑时对我来说很好,尚不清楚为什么茉莉花(不是在茉莉花上开玩笑吗?)说不能在it中执行异步操作。无论如何,您都可以更改上面的代码以在beforeEach中设置所有内容,然后在expect的{​​{1}}中进行操作。