Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 测试RxJS observable跟踪最后发出的值(无完整信号)?_Javascript_Testing_Rxjs_Jestjs_Rxjs6 - Fatal编程技术网

Javascript 测试RxJS observable跟踪最后发出的值(无完整信号)?

Javascript 测试RxJS observable跟踪最后发出的值(无完整信号)?,javascript,testing,rxjs,jestjs,rxjs6,Javascript,Testing,Rxjs,Jestjs,Rxjs6,我做了一些搜索,但找不到我的用例的简单答案。如果已经存在足够类似的问题,我提前道歉 我有一个可观察的,myObservable,它连续地从一个存储流式传输一个值(即,它表示存储的状态)。我想用Jest测试我的observable是否能够在存储发生更改时正确更新 //即每次值更改时,myObservable都会发出一个事件 myObservable.subscribe(x=>console.log(x)) 所以我真正想做的是如下所示: wait myStore.set(0) //在此处插入:检查

我做了一些搜索,但找不到我的用例的简单答案。如果已经存在足够类似的问题,我提前道歉

我有一个可观察的,
myObservable
,它连续地从一个存储流式传输一个值(即,它表示存储的状态)。我想用Jest测试我的observable是否能够在存储发生更改时正确更新

//即每次值更改时,myObservable都会发出一个事件
myObservable.subscribe(x=>console.log(x))
所以我真正想做的是如下所示:

wait myStore.set(0)
//在此处插入:检查“myObservable”流是否为0
等待myStore。设置(5)
//在此插入:检查“myObservable”流是否为5

基本上,我需要一种方法,在任何时间点“点击”到
myObservable
,以查看上次发出的值。如果这是一个n00b问题,很抱歉。

我不确定这是否是一个有效的方法。但是你可以试试这个

这段代码是用Jasmine编写的,我希望它在开玩笑时有点类似

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

我不太确定这是不是一种有效的方法。但是你可以试试这个

这段代码是用Jasmine编写的,我希望它在开玩笑时有点类似

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

此解决方案创建订阅以接收预期值、执行断言和结束测试

虽然有点长,但在我看来,它似乎是惯用的,应该能够随着应用程序反应性需求的增长而扩展

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)
    )
  })
})
import{from,Observable,of}from'rxjs'
从“rxjs/operators”导入{concatMap,finalize,take,tap,toArray}
//示例“定义”使示例得以编译
//将“myObservable”、“myStore”替换为预期结果的实际代码
常数myObservable:Observable=of(123)
康斯特myStore:{
集合:(数字)=>承诺
}=与任何值一样为空
描述('我的测试',()=>{
它('是一个例子',完成=>{
//配置observable以断言发出的值
myObservable.pipe(
//此订阅将在发出2个值后完成
以(2)为例,
//将所有值放入一个数组中
toArray(),
//断言值(已转换为数组)
点击(VAL=>expect(VAL).toBe([0,5]),
//这将确保测试不会“挂起”可观察到的错误
完成(()=>{
//若断言未发生,测试将失败
expect.assertions(1)
完成()
})
).subscribe()
//---选择首选执行方式-“设置存储值”
//选项1:设置0,然后设置5(使用可观测值)
从(myStore.set(0))管道(
concatMap(()=>myStore.set(5))
).subscribe()
//选项2:设置0,然后设置5(使用承诺)
myStore.set(0)。然后(()=>
myStore.set(5)
)
})
})

祝您好运!

此解决方案创建订阅以接收预期值、执行断言并结束测试

虽然有点长,但在我看来,它似乎是惯用的,应该能够随着应用程序反应性需求的增长而扩展

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)
    )
  })
})
import{from,Observable,of}from'rxjs'
从“rxjs/operators”导入{concatMap,finalize,take,tap,toArray}
//示例“定义”使示例得以编译
//将“myObservable”、“myStore”替换为预期结果的实际代码
常数myObservable:Observable=of(123)
康斯特myStore:{
集合:(数字)=>承诺
}=与任何值一样为空
描述('我的测试',()=>{
它('是一个例子',完成=>{
//配置observable以断言发出的值
myObservable.pipe(
//此订阅将在发出2个值后完成
以(2)为例,
//将所有值放入一个数组中
toArray(),
//断言值(已转换为数组)
点击(VAL=>expect(VAL).toBe([0,5]),
//这将确保测试不会“挂起”可观察到的错误
完成(()=>{
//若断言未发生,测试将失败
expect.assertions(1)
完成()
})
).subscribe()
//---选择首选执行方式-“设置存储值”
//选项1:设置0,然后设置5(使用可观测值)
从(myStore.set(0))管道(
concatMap(()=>myStore.set(5))
).subscribe()
//选项2:设置0,然后设置5(使用承诺)
myStore.set(0)。然后(()=>
myStore.set(5)
)
})
})

祝你好运!

它感觉很笨重,但我想这可能行得通?我唯一的问题是测试如何知道一切都完成了?函数可能会在调用最后的
expect
语句之前完成(在最后的更改之后)。勾号(100)将确保所有其他回调都已执行,这是假设
myStore.set()
永远不会超过100ms?感觉很笨拙,但我想这可能行得通?我唯一的问题是测试如何知道所有事情都完成了?函数可能会在调用最终的
expect
语句之前完成(在最终更改之后)。勾号(100)将确保执行所有其他回调是否假设
myStore.set()
的时间从不超过100ms?是否可以将
myObservable
当前实现为主题?另一个问题-是否从
myStore.set()返回
一个承诺,正如您的问题所显示的那样?如果是,它是否会转化为一个有意义的值?@dmcgrandle是的,它是一个
主题
。是的,
myStore.set()
是一个承诺,但它没有解决任何问题。只是我们知道,一旦承诺得到解决,交易就完成了。
myObservable
当前是否作为主题实现?另一个问题-是否从
myStore.set()返回
一个承诺,正如您的问题所显示的那样?如果是,它是否会解析为一个有意义的值?@dmcgrandle是的,它是一个
主题
。是的,
myStore.set()
是一个承诺,但它不会解析任何内容。只是我们知道,一旦