Тестирование RxJS наблюдается, что отслеживает последнее излученное значение (нет полного сигнала)? - PullRequest
0 голосов
/ 22 декабря 2018

Я провел некоторый поиск, но не смог найти простой ответ на мой вариант использования.Я заранее извиняюсь, если уже существует достаточно похожий вопрос по SO.

У меня есть наблюдаемая myObservable, которая непрерывно передает значение из хранилища (то есть оно представляет состояние хранилища).Я хочу проверить с помощью Jest, что моя наблюдаемая может корректно обновляться, когда в магазине происходят изменения.

// i.e. every time the value changes, an event is emitted by myObservable
myObservable.subscribe(x => console.log(x))

Так что я действительно хочу сделать что-то вроде следующего:

await myStore.set(0)
// insert here: check that `myObservable` stream is a 0
await myStore.set(5)
// insert here: check that `myObservable` stream is a 5

По сути, мне нужен способ «нажать» на myObservable в любой момент времени, чтобы увидеть, какое значение было передано в последний раз.Извините, если это не совсем вопрос n00b.

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Это решение создает подписку для получения ожидаемых значений, выполнения утверждений и завершения теста.

Хотя и немного длинная, она кажется мне идиоматичной и должна иметь возможность масштабироваться по мере роста реактивных потребностей вашего приложения.

import { from, Observable, of } from 'rxjs'
import { concatMap, finalize, take, tap, toArray } from 'rxjs/operators'

// sample "definitions" to make the example compile
// replace "myObservable", "myStore" with actual code for expected result
const myObservable: Observable<number> = of(123)
const myStore: {
  set: (number) => Promise
} = null as any

describe('my test', () => {
  it('is an example', done => {
    // configure observable to assert emitted values
    myObservable.pipe(
      // this subscription will complete after emitting 2 values
      take(2),
      // put all the values into a single array
      toArray(),
      // assert the values (that has been converted to array)
      tap(vals => expect(vals).toBe([0, 5]),
      // this will ensure the test does not 'hang' on observable error
      finalize(() => {
        // test will fail if assertion did not happen
        expect.assertions(1)
        done()
      })
    ).subscribe()

    // --- pick preferred way to execute - "set store value"
    // option 1: set 0 then set 5 (using observables)
    from(myStore.set(0)).pipe(
      concatMap(() => myStore.set(5))
    ).subscribe()

    // option 2: set 0 then set 5 (using promises)
    myStore.set(0).then(() =>
      myStore.set(5)
    )
  })
})

Удачи!

0 голосов
/ 22 декабря 2018

Я не совсем уверен, что это эффективный способ.Но вы можете попробовать это.

Этот код написан на Жасмине, надеюсь, он будет несколько похож на Jest.

fit('Should test observable with store', fakeAsync(() => {
  const testData = [1, 2, 3, 4];
  let index = 0;

  myObservable.subscribe(t => {
    expect(t).toBe(testData[index]);
  });

  testData.forEach(td => {
    myStore.set(td)
    tick(100);
    index++;
  });
}));
...