如何在茉莉花单元测试中触发 ngxsAfterBootstrap?
How trigger ngxsAfterBootstrap in jasmine unit tests?
在我的 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 ...
中不存在
我试图获取我的商店实例,使用模拟的 StateContext 作为参数手动调用他的 ngxsAfterBootstrap 方法,但显然,因为模拟了 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步骤中,我们模拟了所有外部依赖,包括public个组件方法(组件方法不是必须的,这取决于我们的方法)。
- 之后在 //Act 中,我们通过简单地调用
来触发 ngOnInit
component.ngOnInit();
- 最后在 //Assert 中我们期望我们的间谍已经被调用。
与 ngxsAfterBootstrap
的方法相同,您应该将其视为一个简单的 class 方法。无需将事情复杂化。
在我的 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 ...
中不存在我试图获取我的商店实例,使用模拟的 StateContext 作为参数手动调用他的 ngxsAfterBootstrap 方法,但显然,因为模拟了 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步骤中,我们模拟了所有外部依赖,包括public个组件方法(组件方法不是必须的,这取决于我们的方法)。
- 之后在 //Act 中,我们通过简单地调用 来触发 ngOnInit
component.ngOnInit();
- 最后在 //Assert 中我们期望我们的间谍已经被调用。
与 ngxsAfterBootstrap
的方法相同,您应该将其视为一个简单的 class 方法。无需将事情复杂化。