最近在 jasmine-marbles 0.5.0 中添加了对时间进展的支持(参见 jasmine-marbles PR #38 )。附加的测试规范被添加到包中,展示了实现您想要的几种可能方法中的一种。以下是我能够使用您的 Stackblitz 示例汇总的一些选项。
选项1
当您在测试方法之外(例如 in beforeEach
)初始化源 observable 时,您必须显式初始化并传递测试调度程序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
参数为 left 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 会报告警告“SPEC HAS NO EXPECTATIONS”。
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 }]);
});
});
});