我一直在整个应用程序中广泛使用NGXS,但是有些事情我仍然无法以适当的方式完成,到目前为止,文档或此处提出的其他问题都没有帮助。其中之一就是测试动作,特别是测试从另一个动作中调用了某个动作。检查以下内容:
store.ts
@Action(ActionToBeTested)
public doActionToBeTested(
ctx: StateContext<MyState>,
): void {
const state = ctx.getState();
// update state in some way
ctx.patchState(state);
this.restApiService.save(state.businessData)
.pipe(
mergeMap(() =>
this.store.dispatch(new SomeOtherAction(state.businessData)),
)
)
.subscribe();
}
store.spec.ts
it('should test the state was update, restapi was called and action was dispatched', async(() => {
store.reset({...someMockState});
store.dispatch(new ActionToBeTested());
store
.selectOnce((state) => state.businessData)
.subscribe((data) => {
expect(data).toBe('Something I expect');
expect(restApiServiceSpy.save).toHaveBeenCalledTimes(1);
});
}));
以此,我可以测试状态是否已更新并且调用了其余服务,但是我根本无法测试动作SomeOtheAction
是否已调度。自将第一个动作(我知道有点疯狂)分配给此answer中描述的内容后,尝试在商店中进行监视以来,我已经尝试了很多事情,但没有成功。
有人遇到类似的困难并找到了解决方案。如果是这样,请指出正确的方向,我将很乐意自己走这条路。谢谢
答案 0 :(得分:1)
解决问题将近一整天后,我得出了可以视为解决方案的解决方案。如下:
it('should test the state was update, restapi was called and action was dispatched', (done) => {
store.reset({...someMockState});
actions$.pipe(ofActionSuccessful(DeleteSource)).subscribe((_) => {
const updatedData = store.selectSnapshot(
(state) => state.businessData,
);
expect(updatedData).toBe('Something I expect due to the first action');
expect(updatedData).toBe('Something I expect due to the SECOND action');
expect(restApiServiceSpy.save).toHaveBeenCalledTimes(1);
done();
});
store.dispatch(new ActionToBeTested());
});
那么,这是怎么回事?正如@Eldar在问题评论中所建议的那样,我决定测试最终状态,而不是检查该动作是否真正被调用。为了使其正常工作,我必须按照here所述插入动作流,并使用操作员ofActionSuccessful
“监听”“动作成功”事件。这样就可以仅在操作完成后检查状态,而不必只是分派状态,这样我就可以测试一切是否都处于最终状态。
几件事要记住:
done
函数,否则会出现超时错误。done
仅在传递给it()
函数的回调没有与async
函数一起包装的情况下起作用。undefined
。最初,我的模拟服务方法返回of()
而不是of(undefined)
,这在某些情况下会引起问题。delay
这样用已定义的of(undefined).delay(1)
来定义模拟,因此您可以控制通话和期望的时间。希望这对某人有帮助。