Rxjs 如何测试一个无法完成的内部可观察对象?

Rxjs 如何测试一个无法完成的内部可观察对象?,rxjs,jestjs,redux-observable,Rxjs,Jestjs,Redux Observable,我正在使用jest测试一个redux observableepic,它派生出一个使用observable.fromEvent创建的内部observable.fromEvent并在发出动作之前监听特定的按键 我正在努力测试内部可观察对象何时没有收到这个特定的按键,因此没有发出动作 使用jest,以下超时: import { Observable, Subject } from 'rxjs' import { ActionsObservable } from 'redux-observable' i

我正在使用
jest
测试一个
redux observable
epic,它派生出一个使用
observable.fromEvent创建的内部observable.fromEvent
并在发出动作之前监听特定的按键

我正在努力测试内部可观察对象何时没有收到这个特定的按键,因此没有发出动作

使用jest,以下超时:

import { Observable, Subject } from 'rxjs'
import { ActionsObservable } from 'redux-observable'
import keycode from 'keycode'

const closeOnEscKeyEpic = action$ =>
    action$.ofType('LISTEN_FOR_ESC').switchMapTo(
        Observable.fromEvent(document, 'keyup')
            .first(event => keycode(event) === 'esc')
            .mapTo({ type: 'ESC_PRESSED' })
    )

const testEpic = ({ setup, test, expect }) =>
    new Promise(resolve => {
        const input$ = new Subject()
        setup(new ActionsObservable(input$))
            .toArray()
            .subscribe(resolve)
        test(input$)
    }).then(expect)

// This times out
it('no action emitted if esc key is not pressed', () => {
    expect.assertions(1)
    return testEpic({
        setup: input$ => closeOnEscKeyEpic(input$),
        test: input$ => {
            // start listening
            input$.next({ type: 'LISTEN_FOR_ESC' })

            // press the wrong keys
            const event = new KeyboardEvent('keyup', {
                keyCode: keycode('p'),
            })
            const event2 = new KeyboardEvent('keyup', {
                keyCode: keycode('1'),
            })
            global.document.dispatchEvent(event)
            global.document.dispatchEvent(event2)

            // end test
            input$.complete()
        },
        expect: actions => {
            expect(actions).toEqual([])
        },
    })
})
我的期望是,调用
input$.complete()
会导致
testEpic
中的承诺得到解决,但对于这个测试,它不会


我觉得我错过了什么。有人知道为什么这不起作用吗?

我还是Rx/RxJS的新手,所以如果这个答案的术语不适用,我深表歉意。不过,我能重现你的情景

内部可观察对象(
observable.fromEvent
)正在阻止外部可观察对象。
ActionsObservable
上的已完成事件在内部可观察对象完成之前不会传播

使用此测试脚本尝试以下代码段:

  • 运行代码段
  • 按非退出键。
    • 不应向控制台打印任何内容
  • 选择“监听逃生!”按钮
  • 按非退出键。
    • 钥匙代码应打印到控制台上
  • 选择“完成!”按钮
  • 按非退出键。
    • 钥匙代码应打印到控制台上
  • 按退出键。
    • 钥匙代码应打印到控制台上
    • onNext回调应将ESC_按下的操作打印到控制台
    • onComplete回调应打印到控制台
  • document.getElementById('complete')。onclick=onComplete
    document.getElementById('listenForEsc')。onclick=onListenForEsc
    const actions=new Rx.Subject()
    const epic=动作$=>
    动作$.pipe(
    Rx.operators.filter(action=>action.type==='LISTEN\u FOR\u ESC'),
    Rx.operators.switchMapTo(
    Rx.Observable.fromEvent(文档“keyup”).管道(
    Rx.operators.tap(event=>{console.log('keyup:%s',event.keyCode)}),
    Rx.operators.first(event=>event.keyCode===27),//转义
    mapTo({type:'ESC_PRESSED'}),
    )
    )
    )
    epic(actions.asObservable()).subscribe(
    action=>{console.log('next:%O',action)},
    error=>{console.log('error:%O',error)},
    ()=>{console.log('complete')},
    )
    函数onListenForEsc(){
    actions.next({type:'LISTEN_FOR_ESC'})
    }
    函数onComplete(){
    actions.complete()
    }
    
    完成
    留心逃跑