UPD
rxjs 从 6.0.0 版本开始提供时间进度语法。所以你的测试可能看起来像:
it('generate the stream correctly', () => {
testScheduler.run(helpers => {
const { cold, expectObservable, expectSubscriptions } = helpers;
const input = ' -a-b-c|';
const expected = '-- 9ms a 9ms b 9ms (c|)';
/*
// Depending on your personal preferences you could also
// use frame dashes to keep vertical aligment with the input
const input = ' -a-b-c|';
const expected = '------- 4ms a 9ms b 9ms (c|)';
// or
const expected = '-----------a 9ms b 9ms (c|)';
*/
const result = cold(input).pipe(
concatMap(d => of(d).pipe(
delay(10)
))
);
expectObservable(result).toBe(expected);
});
原始答案
终于找到了一些解决方法,不确定它是否适用于所有情况。
所以这里是我们修改函数的文件:
import { Observable } from "rxjs";
import { delay } from "rxjs/operators";
export function modify<T>(source: Observable<T>): Observable<T> {
return source.pipe(delay(1000));
}
这里的主要思想是将所有操作符作为对象导入,并对这些对象的方法进行监视:
import * as operators from "rxjs/operators";
...
spyOn(operators, "delay")
这里的问题是我得到错误的情况:
Error: <spyOn> : delay is not declared writable or has no setter
为避免此错误,我只是更改了对象中的属性描述符:
/**
* Changes property descriptor to make possible to use spyOn function for imported
* modules.
*/
function spyOnOperator(obj: any, prop: string): any {
const oldProp: Function = obj[prop];
Object.defineProperty(obj, prop, {
configurable: true,
enumerable: true,
value: oldProp,
writable: true
});
return spyOn(obj, prop);
}
所以我的规范文件现在看起来像:
import { cold, getTestScheduler, hot, time } from "jasmine-marbles";
import * as operators from "rxjs/operators";
import { modify } from "./modify";
describe("Test delay: ", () => {
it("mock chain style call (modify function)", () => {
const originalDelay: Function = operators.delay;
const values: any = {
a: "test",
x: "test"
};
const source: TestHotObservable = hot("-a", values);
const delayTime: number = time("--|");
const result: TestColdObservable = cold("---x", values);
spyOnOperator(operators, "delay").and.callFake(() => {
return originalDelay.call(this, delayTime, getTestScheduler());
});
expect(modify(source)).toBeObservable(result);
});
});