Что считается правильным способом тестирования методов, которые возвращают наблюдаемые http? - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть проект TypeScript, который я хотел бы развернуть в виде пакета JS NPM.Этот пакет выполняет некоторые http-запросы с использованием функций rxjs ajax.Теперь я хотел бы написать тесты для этих методов.

В какой-то момент у меня есть такой метод (упрощенный!):

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

Я знаю о базовом тестировании, например, с spyOn Я могу высмеять ответ от сервера.Но как бы я на самом деле протестировал http-запрос?

В документации jasmine сказано, что я не могу выполнять асинхронную работу в части 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 голосов
/ 09 февраля 2019

Вам нужно смоделировать ajax.get, чтобы вернуть 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?

EDIT # 27: Приведенный выше код отлично работает для меня, когда я запускаю jest, не совсем понятно, почему jasmine (jest не запускается на jasmine?) Говорит, что не может выполнить асинхронность в it s.В любом случае вы можете просто изменить приведенный выше код, чтобы настроить все в beforeEach, и просто набрать expect в it.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...