Поддержка прогрессии времени была недавно добавлена ( см. Jasmine-marbles PR # 38 ) в jasmine-marbles 0.5.0. В пакет были добавлены дополнительные тестовые спецификации, которые демонстрируют один из нескольких возможных способов достичь желаемого. Вот несколько вариантов, которые я смог собрать вместе, используя ваш образец Stackblitz.
Вариант 1
Когда вы инициализируете источник, наблюдаемый за пределами метода теста (например, в beforeEach
), вы должны явно инициализировать и передать планировщик теста в timeout
, чтобы заставить expect().toBeObservable()
работать. Однако обратите внимание, что это изменение нарушит тест «следует работать с toPromise». (Я не знаю почему, но toPromise()
, похоже, не работает с этим подходом.)
describe('Marble testing with timeout', () => {
let source;
beforeEach(() => {
// You must explicitly init the test scheduler in `beforeEach`.
initTestScheduler()
source = cold('a', { a: { id: 'a' } }).pipe(
// You must explicitly pass the test scheduler.
timeout(500, getTestScheduler()),
filter((a) => false),
catchError(err => {
return of({ timeout: true })
}),
take(1)
);
});
it('should work with toBeObservable', () => {
const expected = cold('500ms (a|)', { a: { timeout: true } });
expect(source).toBeObservable(expected);
});
});
Вариант 2
Вы можете немного реорганизовать вещи и инициализировать источник, наблюдаемый внутри метода тестирования (, а не в beforeEach
). Вам не нужно явно инициализировать планировщик теста (jasmine-marbles сделает это за вас до запуска метода теста), но вам все равно придется передать его в timeout
. Обратите внимание, как функция createSource
может использоваться с планировщиком тестов или планировщиком по умолчанию (если аргумент scheduler
оставлен undefined
). Этот параметр работает как с тестом «следует работать с toPromise», так и с тестом «должен работать с toBeObservable».
describe('Marble testing with timeout', () => {
const createSource = (scheduler = undefined) => {
return cold('a', { a: { id: 'a' } }).pipe(
// You must explicitly pass the test scheduler (or undefined to use the default scheduler).
timeout(500, scheduler),
filter((a) => false),
catchError(err => {
return of({ timeout: true })
}),
take(1)
);
};
it('should work with toPromise', async () => {
const source = createSource();
expect(await source.toPromise()).toEqual({ timeout: true });
});
it('should work with toBeObservable', () => {
const source = createSource(getTestScheduler());
const expected = cold('500ms (a|)', { a: { timeout: true } });
expect(source).toBeObservable(expected);
});
});
Вариант 3
Наконец, вы можете пропустить передачу планировщика тестов в timeout
, если вы явно используете метод run
планировщика тестов, но вы должны использовать expectObservable
(в отличие от expect().toBeObservable()
. Он работает просто отлично, но Jasmine выдаст предупреждение «У СПЕКА НЕТ ОЖИДАНИЙ».
describe('Marble testing with timeout', () => {
let source;
beforeEach(() => {
source = cold('a', { a: { id: 'a' } }).pipe(
timeout(500),
filter((a) => false),
catchError(err => {
return of({ timeout: true })
}),
take(1)
);
});
it('should work with scheduler and expectObservable', () => {
const scheduler = getTestScheduler();
scheduler.run(({ expectObservable }) => {
expectObservable(source).toBe('500ms (0|)', [{ timeout: true }]);
});
});
});