gpt4 book ai didi

rxjs5 - 在RxJS中测试异步可管道运算符

转载 作者:行者123 更新时间:2023-12-01 06:53:28 35 4
gpt4 key购买 nike

有时我们有一些函数,这些函数会使用诸如延迟之类的异步运算符来修改原始源。

假设我们有一些非常简单的东西:

// Old syntax
function modify(source) {
return source.delay(1000);
}

我正在使用弹珠测试RxJ,所以我的测试看起来像:

it("mock chain style call (modify function)", function() {
var values = {
a: "test",
x: "test"
};

var source = hot( "-a", values);
var delayTime = time( "--|");
var result = cold( "---x", values);

var originalDelay = Rx.Observable.prototype.delay;
spyOn(Rx.Observable.prototype, "delay").and.callFake(function () {
return originalDelay.call(this, delayTime, jm.getTestScheduler());
});

expect(modify(source)).toBeObservable(result);
});

与rxjs库中用于测试的内容几乎相同: https://github.com/ReactiveX/rxjs/blob/master/spec/operators/delay-spec.ts

但是我们必须修补Observable.delay函数,因为我们没有直接访问它的权限。
而且效果很好。

但是我们决定从RxJs开始使用可管道运算符。有什么想法如何测试此功能:

// New syntax
function modify(source) {
return source.pipe(Rx.operators.delay(1000));
}

看起来像什么?

JsBin demo

最佳答案

UPD

从6.0.0版开始,Time progression syntax在rxjs中可用。
因此您的测试可能如下所示:

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);
});
});

关于rxjs5 - 在RxJS中测试异步可管道运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49501195/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com