angular - 如何在 jasmine 单元测试中触发 ngxsAfterBootstrap?
问题描述
在我的 Angular 应用程序中,我使用 NGXS 和 Jasmine。
在我的一些商店中,我使用 ngxsAfterBootstrap 作为初始化,在其中调度一些操作。
我不能使用 ngxsOnInit,因为不知道具体原因,但是我无法从我的 RouteState 选择器中获取最新的 url 参数(在 ngxsOnInit 中始终未定义,即使我订阅了这些选择器并等待了一些多少时间)
但是,使用 ngxsAfterBootstrap 我得到了这些值。
所以,在我的单元测试中,我想测试这个初始化,但我没有找到任何解决方案来触发 ngxsAfterBootstrap 方法。
根据 NGXS 文档(https://www.ngxs.io/advanced/life-cycle),ngxsAfterBootstrap 将通过 APP_BOOTSTRAP_LISTENER 触发,所以我认为这是我们使用 ngModule 的 'bootstrap' 属性时,它不存在于TestBed.configureTestingModule ...
我试图获取我的商店实例,手动调用他的 ngxsAfterBootstrap 方法,并将 StateContext 模拟为参数,但显然,因为 StateContext 是模拟的,所以当我使用他的调度时它不会触发我的动作......
你知道任何“干净”的解决方案吗?(这里的干净只是为了不修改我的实现以使单元测试正常工作)
谢谢 !(对不起,我的英语不好)
编辑:
我最终做了什么:
productStore = TestBed.inject(ProductState);
...
const stateContextMocked = {
getState: jasmine.createSpy(),
setState: jasmine.createSpy(),
patchState: jasmine.createSpy(),
dispatch: jasmine.createSpy(),
} as StateContext<IProduct>;
...
productStore.ngxsAfterBootstrap(stateContextMocked);
...
expect(stateContextMocked.dispatch).toHaveBeenCalledWith(new GetProductAction(productIdMocked));
我之前尝试过这样做,但我不喜欢它,因为我无法使用自动传入 ngxsAfterBootstrap 参数的“真实”StateContext 对象。
所以,我不能得到我的派遣结果。
但事实上,我可以只测试我的调度方法是否已被调用,并进行另一个测试来测试自己调度的动作。
这甚至是一个更好的方法^^
解决方案
假设我们要测试 ngOnInit。
- 在测试的 //Arrange 步骤中,我们模拟了所有外部依赖项,包括公共组件方法(顺便说一下,组件方法不是强制性的,这取决于我们的方法)。
- 然后在 //Act 中,我们通过简单地调用来触发 ngOnInit
component.ngOnInit();
- 最后在 //Assert 中,我们期望我们的间谍已经被调用。
同样的方法是 with ngxsAfterBootstrap
,你应该把它看作一个简单的类方法。没有必要把事情复杂化。
推荐阅读
- vue.js - Vuex:添加项目后,Vuetify 扩展面板插槽不会更新
- javascript - JSON 被错误解析
- python - 如何根据值更改 Excel 单元格颜色?
- jestjs - 开玩笑 - 在 beforeEach 完成之前执行测试
- c# - 如何从 C# 中的 TimePicker(WPF) 获取价值?
- c# - C# 重写静态方法
- matlab - 使用了“drawnow”,但在脚本结束之前无法使用菜单栏
- angular - 带有@input属性的Angular 7 2路绑定
- powershell - 如何使用 Win32_UserAccount 重命名方法?
- google-cloud-platform - 通过 Terraform 提供具有静态 IP 的 GCP VM 实例