可观察到的奇特结果:用茉莉花大理石测试

时间:2020-02-12 17:02:28

标签: angular unit-testing jasmine jestjs jasmine-marbles

我正在用Jest测试的Angular 7中有一个小功能。该函数如下所示:

private checkFreeProduct(allowance: SubscriberConnectivityAllowanceInterface): Observable<SubscriberConnectivityAllowanceInterface> {

    // TODO: This is currently just a temp function to be extended when required
    return of(allowance);

}

如您所见,目前,它所做的只是根据其输入创建一个可观察对象,但是它正在开发中,并将得到扩展。

我正在像这样用Jest测试它:

it('should return an observable of the allowance', () => {

    const allowance: SubscriberConnectivityAllowanceInterface = {
        hotspotAuthenticated: HotspotAuthenticationEnum.TRUE,
        remainingOctets: 100,
        remainingSeconds: 200,
        activeProductCost: ConnectivityProductCostEnum.PAID,
        activeProductDuration: ConnectivityProductDurationEnum.FLIGHT,
        activeProductType: ConnectivityProductTypeEnum.PREMIUM,
        connectivityProducts: []
    };

    const expected = hot('a|', {
        a: allowance
    });

    expect(hotspotService['checkFreeProduct'](allowance)).toBeObservable(expected);

});

但是,由于某些计时问题,测试失败。 expected的可观察结果如下:

[
  {
    "frame": 0,
    "notification": {
      "error": undefined,
      "hasValue": true,
      "kind": "N",
      "value": {
        "activeProductCost": "paid",
        "activeProductDuration": "flight",
        "activeProductType": "premium",
        "connectivityProducts": [],
        "hotspotAuthenticated": 1,
        "remainingOctets": 100,
        "remainingSeconds": 200
      }
    }
  },
  {
    "frame": 10,
    "notification": {
      "error": undefined,
      "hasValue": false,
      "kind": "C",
      "value": undefined
    }
  }
]

,从函数调用hotspotService['checkFreeProduct'](allowance)创建的可观察对象如下所示:

[
  {
    "frame": 0,
    "notification": {
      "error": undefined,
      "hasValue": true,
      "kind": "N",
      "value": {
        "activeProductCost": "paid",
        "activeProductDuration": "flight",
        "activeProductType": "premium",
        "connectivityProducts": [],
        "hotspotAuthenticated": 1,
        "remainingOctets": 100,
        "remainingSeconds": 200
      }
    }
  },
  {
    "frame": 0, // <------- this is the only difference
    "notification": {
      "error": undefined,
      "hasValue": false,
      "kind": "C",
      "value": undefined
    }
  }
]

现在我不确定为什么这些可观察物会产生两种辐射,但我会继续讨论。我不明白的是为什么函数调用中的observable会在第0帧发出两个事件。我已经尝试了hot()cold(),并在这些调用中尝试了各种弹珠,但没有喜悦。有人可以解释吗?

1 个答案:

答案 0 :(得分:2)

您询问的有关发出两个事件的问题是由于大理石hot('a|')-第一个发出的是您希望断言'a'的值,第二个发出的是表示可观察到的热门{{ 1}}。这可以从您在问题中添加的那些事件中的Notification-> Kind属性推断出来。例如:“ kind”:“ N”->发出的值。 kind“:” C“->可观察的完成。

答案: 要修复单元测试,只需将大理石更改为'|',以使它们都在同一时间范围内发射。我已经对此进行了测试,并且可以正常工作。

不同时间段的原因: 热和冷会创建可观察的流,这些流会在特定的时间间隔内发射值。大理石表示随着时间推移可观察物上发生的动作。

  • '(a|)'-表示时间单位。
  • --表示从流发出的值。
  • [a-z0-9]-表示可观察流的完成。
  • |-表示可观察流中的错误。
  • #-表示在同一时间范围内发射的值的分组。

为您的解决方案()-表示同时发出值hot('(a|'))并在同一时间范围内完成可观察的流。

参考: https://github.com/jisaacks/RxJS/blob/master/doc/writing-marble-tests.md https://medium.com/@bencabanes/marble-testing-observable-introduction-1f5ad39231c