Угловое тестирование, не вызывающее ожидание, приводит к тому, что Spec не имеет ожиданий

У меня есть служба, которая делает HTTP-вызов к моему бэкэнду, я пытаюсь проверить, получит ли он ответ пользователей, после запуска теста я получаю Spec has no expectation, хотя у меня есть один в подписке. Все эти тесты пройдены, но 2 имеет результат SPEC HAS NO EXPECTATION

вот мой код:

describe('Auth Service Testing', () => {
  let httpClientSpy: { get: jasmine.Spy };
  let authServ: AuthService;
  let authAct: AuthActions;
  let userAct: UserActions;
  let checkoutAct: CheckoutActions;
  let productAct: ProductActions;
  let store: Store<any>;
  let localStorageServ: LocalStorageService;
  let authResponse;
  const expectedUserResponse = {
    users: [],
    count: 25,
    current_page: 1,
    pages: 2
  };

  beforeEach(() => {
    httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']);
    authServ = new AuthService(
      <any>httpClientSpy,
      authAct,
      userAct,
      checkoutAct,
      productAct,
      store,
      localStorageServ
    );
  });

  it('should get users response', () => {
    httpClientSpy.get.and.returnValue(asyncData(expectedUserResponse));

    authServ.authorized().subscribe((users) => {
      authResponse = users;
      expect(users).toEqual(jasmine.objectContaining({ users: [] }));
    });

  });

  it('should equal to expected users response', () => {
    expect(authResponse).toEqual(expectedUserResponse);
  });

  it('should return null if theres an error', () => {
    httpClientSpy.get.and.returnValue(asyncError(expectedUserResponse));
    authServ
      .authorized()
      .subscribe(() => {}, (error) => expect(error).toBe(null));
  });
});

Кроме того, я следовал руководству по тестированию углового HTTP тесту angular. Мне интересно, баг или еще что.

результаты кармы:

Auth Service Testing
SPEC HAS NO EXPECTATIONS should return null if there's an error
SPEC HAS NO EXPECTATIONS should get users response
should equal to expected users response

ОБНОВЛЕНИЕ

Отсутствует следующий код: expect(httpClientSpy.get.calls.count()).toBe(1); это странно, я думал, что этот вызов делает HTTP-запрос на получение httpClientSpy.get.and.returnValue(asyncError(expectedUserResponse));

но в тесте на ошибку в руководстве у них этого нет. Может ли кто-нибудь пролить свет на это?

много любви из Северной Кореи. ‹3


person aRtoo    schedule 18.09.2019    source источник


Ответы (1)


Очень сложно провести модульное тестирование наблюдаемого с помощью подписки. Есть много пограничных случаев, когда модульный тест пройдет, но должен был провалиться. Даже если вы используете обратный вызов done() с финализатором или обработчиком ошибок.

Всякий раз, когда наблюдаемый объект выдает только один ожидаемый результат, вместо этого следует использовать обещание.

  it('should get users response', async () => {
    httpClientSpy.get.and.returnValue(asyncData(expectedUserResponse));

    const users = await = authServ.authorized().toPromise();

    expect(users).toEqual(jasmine.objectContaining({ users: [] }));
  });

Всякий раз, когда наблюдаемый объект выдает несколько значений, вы можете преобразовать его в массив и по-прежнему использовать обещание.

  it('should get users response', async () => {
    httpClientSpy.get.and.returnValue(asyncData(expectedUserResponse));

    const users = await = authServ.authorized().pipe(
        toArray()
    ).toPromise();

    expect(users).toEqual(jasmine.objectContaining([{ users: [] }]));
  });

Преимущество toPromise() в том, что он всегда разрешается. Даже если наблюдаемое не выдает никаких значений, и оно не проходит модульный тест, если внутри наблюдаемого возникают какие-либо неперехваченные ошибки.

person Reactgular    schedule 18.09.2019
comment
это работает, но почему угловая документация рекомендует это. это намного проще и проще. Поэтому каждый раз, когда я проверяю какие-либо наблюдаемые, я использую toPromise() - person aRtoo; 18.09.2019
comment
@aRtoo Я знаю, но документация неверна. Их примеры могут потерпеть неудачу. В этом разница между опытом и теорией. o.subscribe(v => expect(v).toBe(1), () => done.fail(), ()=> done()); будет проходить, если o никогда не излучает. - person Reactgular; 18.09.2019
comment
Я читал угловой пост и читал о жалобах на подписку на HTTP-ответ, так что это правда или просто для тестирования. еще раз спасибо, сэр. ты козел. - person aRtoo; 18.09.2019
comment
@aRtoo предназначен только для модульного тестирования, и это связано с тем, как rxjs обрабатывает отправку данных и завершение как отдельные события. Таким образом, наблюдаемое может завершиться, может не завершиться и может ничего не излучать. Разработчик модульного тестирования должен обрабатывать эти крайние случаи, а люди — нет. Таким образом, это приводит к плохим модульным тестам, но переход на промисы упрощает вашу работу. Это не означает, что вы должны использовать обещания в своем приложении вместо наблюдаемых. - person Reactgular; 18.09.2019
comment
Огромное спасибо. это проясняет все сейчас. Я буду иметь это в виду. ценю помощь, сэр. - person aRtoo; 18.09.2019