В чем разница между fakeAsync и асинхронным тестированием в angular2

Я знаю, что функция tick() использует fakeAsync. А также я могу использовать fixture.whenStable().then() с async и fakeAsync.

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

Примечание: я хочу использовать Fake Service или Stub в обоих сценариях.

Ответ 1

По большей части они могут использоваться взаимозаменяемо. Я не могу придумать что-либо с головы, в котором один из них необходим, за исключением случаев, когда компоненты, внешние шаблоны и стили которых не скомпилированы в компонент для тестирования (т.е. С использованием SystemJS). При использовании SystemJS вызовы XHR выполняются для внешних шаблонов и стилей. fakeAsync не может использоваться при выполнении XHR-вызовов. С другой стороны, при использовании Webpack внешние шаблоны и стили компилируются inline, поэтому вы можете использовать fakeAsync.

Кроме этого, я думаю, что это вопрос предпочтения стиля. Я могу сказать, что вам нужно сделать несколько асинхронных вызовов, например, в этом примере. Вам нужны вложенные вызовы fixture.whenStable(), вызов которых начинает выглядеть довольно уродливым.

fixture.detectChanges();
fixture.whenStable().then(() => {
  expect(something)

  changeSomething()
  fixture.detectChanges();
  fixture.whenStable().then(() => {
    expect(something)
    changeSomething();
    fixture.detectChanges()

    fixture.whenStable().then(() => {
      expect(somthingeElse)
    })
  })
})

Это может выглядеть чище (и проще рассуждать) без всех этих fixture.whenStables()

fixture.detectChanges();
tick();
expect(something)

changeSomething()
fixture.detectChanges();
tick();
expect(somethingElse)

changeSomething()
fixture.detectChanges();
tick();
expect(somethingElse);

Еще одна вещь, которую я могу добавить, - это OCD, мне всегда нужно проверить, что мои вызовы в fixture.whenStable() называются

fixture.whenStable().then(() => {
  expect(...)
  console.log('called...')
})

Представьте, что вы забыли обернуть тест в async. Без этого тест завершится до разрешения fixture.whenStable, и вы никогда не узнаете об этом. Это будет похоже на пройденный тест, который является ложным. Фактически произошло то, что утверждение даже не называлось.

По этой причине я действительно отходил от async. Но если вам нравится этот стиль и доверяйте себе, что вы всегда завершаете тест в async, тогда придерживайтесь его. Но с fakeAsync все называется синхронно, поэтому нет никаких шансов на то, что утверждение не будет вызвано.