如何在退出 Jasmine 测试之前测试 Observable 是不是已发布事件?

Posted

技术标签:

【中文标题】如何在退出 Jasmine 测试之前测试 Observable 是不是已发布事件?【英文标题】:How to test if an Observable has published an event or not before exiting a Jasmine test?如何在退出 Jasmine 测试之前测试 Observable 是否已发布事件? 【发布时间】:2020-10-14 22:08:56 【问题描述】:

如果我有这样的场景:

it('some observable', /*done*/() => 
    
    const someService = TestBed.get(SomeService);

    const subscription = someService.someObservable.subscribe(value => 
        expect(value).toEqual('some value');
        subscription.unsubscribe();
        /*done();*/
    );

    // This method is supposed to cause the Observable to publish the value to all subscribers.
    someService.setValue('some value');
);

如果 Observable 从不发布事件,我怎么能通过测试?这种情况有几个问题。首先,如果 Observable 从未发布事件,则 done() 方法永远不会被调用。另外,如果它不发布事件,我的测试怎么知道?它不会看起来像失败,Jasmine 只会打印测试没有“预期”或类似的东西。

更新:我意识到我不需要 done() 函数,因为我现在在每次测试之前重置 TestBed。但是,如果 Observable 没有触发,测试不会失败,这仍然不能解决问题。

【问题讨论】:

【参考方案1】:

就像你提到的,我认为你可以利用 done 函数。

it('some observable', (done) =>  // put done in the callback
    
    const someService = TestBed.get(SomeService);

    const subscription = someService.someObservable.subscribe(value => 
        expect(value).toEqual('some value');
        done(); // call done to let jasmine know that you're done with the test
    );

    // This method is supposed to cause the Observable to publish the value to all subscribers.
    someService.setValue('some value');
);

如果 observable 没有发布任何事件,done 将不会被调用,测试将挂起并显示 async timeout error

【讨论】:

嗯,这似乎不是在发布火车上运行单元测试的好策略。没有其他方法可以知道 Observable 从未触发过事件吗? ***.com/questions/48389737/… 看看,也许能帮上忙。【参考方案2】:

这是我最终这样做的方式:

it('some observable', () => 
    
    const someService = TestBed.get(SomeService);

    const someValue = 'some value';
    const spy = jasmine.createSpy('someSpy');

    const sub = someService.someObservable.subscribe(spy);
    someService.setValue(someValue);
    expect(spy).toHaveBeenCalledWith(someValue);
    sub.unsubscribe();
);

我不确定为什么会这样,因为我认为 Observables 是异步的。但它似乎在不担心异步的情况下工作。也许我只是走运了,问题会在稍后出现。

【讨论】:

以上是关于如何在退出 Jasmine 测试之前测试 Observable 是不是已发布事件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用jasmine-marbles测试rxjs管道中的timeout()

如何在 Jasmine 测试中测试 $scope?

使用 Jasmine 测试 Node 项目

如何在 Jasmine 中使用 React 测试工具

如何在 jasmine 中编写单元测试用例?

如何使用Jasmine Unit测试测试私有方法