该 Component 具有5个依赖:
SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

为了修复 bug,我需要引入 checkout service 和 cart service.

如果直接在该构造函数里注入,这实际上算是修改了 constructor signature,按照 Spartacus 编程规范,这算是引入了 breaking change - 重大更改。

但我们观察到,该 Component 类的依赖之一,checkoutDeliveryService 内部,具有 checkout service 和 cart service.

SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

如此一来,我们可以把代码移到 checkoutDeliveryService 里编写,这样就不会在 Delivery Component 里引入依赖了。
我们分析上图 Checkout Delivery Service 类,其具有5个依赖,两个 store,存储 state 信息,三个 service 类:

  • ActiveCartService
  • UserIdService
  • CheckoutService
    以 ActiveCartService 为例:

SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

使用如下代码:

  class ActiveCartServiceStub implements Partial<ActiveCartService>

可以构造一个 MockActiveCartService 出来。

使用 Partial 方法,可以只实现 ActiveCartService 的部分方法。

SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

TestBed 用于创建待测试的组件及依赖:
SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

上图的 TestBed.configureTestingModule 只是第一步,还需要调用 TestBed.inject 方法,注入上图 82,83 和 84 行 provide 后面的方法名,返回被注入的类实例:
SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

看下图的单元测试代码:
SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

inject 接受两个参数,第一个参数类型是数组,存放带注入的 token,本例是 checkoutDeliveryService,第二个参数是一个函数,这个函数包含业务逻辑,且输入参数为第一个参数 token 数据待注入的内容。当该函数被调用时,输入参数的 token 包含了被 Angular DI 框架注入好的实例。这个用法很像 SAP UI5 异步加载 library 依赖的实现方式。

而 Ngrx store 的依赖 mock,我们需要在 TestBed.configureTestingModule 的 imports 区域里,维护真实的 StoreModule.forRoot 和 forFeature 返回的数据。

SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

然后调用 TestBed.inject(Store)

SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

接下来就可以调用该方法返回的实例的 dispatch 方法,往 store 里插入测试数据了。

getSupportedDeliveryModes 方法内部会调用 loadSupportedDeliveryModes,因此使用 spyOn 方法,就可以监控后者是否被调用过。

SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

一旦调用 service 的 setDeliveryMode 方法,就会触发 store.dispatch 操作,因此 loading 标志位会设置为 true

SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

又比如 reset 方法,底层会调用 store.dispatch 操作,且传入一个 ResetSetDeliveryModeProcess 的 action. 这个调用也可以被监控。

SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

更多Jerry的原创文章,尽在:"汪子熙":
SAP 电商云 Spartacus UI DeliveryComponent 的依赖设计

相关文章: