I have a little function in Angular 7 that I am testing with Jest. The function looks like this:
private checkFreeProduct(allowance: SubscriberConnectivityAllowanceInterface): Observable<SubscriberConnectivityAllowanceInterface> {
// TODO: This is currently just a temp function to be extended when required
return of(allowance);
}
As you can see, for the moment all it is doing is creating an observable from its input, but it is under development and will be extended.
I am testing it with Jest like this:
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);
});
However, the test is failing because of some timing issue. The expected
observable result looks like this:
[
{
"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
}
}
]
and the observable created from the function call hotspotService['checkFreeProduct'](allowance)
looks like this:
[
{
"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
}
}
]
Now I'm not exactly sure why there are two emissions from these observables, but I'll go with it. What I don't understand is why the observable from the function call emits two events, both on frame 0. I have tried both hot()
and cold()
, and have experimented with various marbles in these calls but no joy. Can someone please explain?
The question you asked about two events emitted is because of the marble hot('a|')
- 1st one is emitting the value that you wish to assert 'a' and second is emitted to indicate the completion of the hot observable '|'
. This can be inferred from the Notification -> Kind property in those events that you have added in your question. Ex: "kind": "N" -> Value emitted. kind": "C" -> completion of observable.
Answer : To fix your unit test, just change the marble to '(a|)'
, so that both of them are emitted in the same time frame. I have tested this and it works.
Reason for different time frames: The hot and cold create observable streams that emit values on specific time intervals. Marbles denote actions that happen over time on observables.
-
- denotes a unit of time frame. [a-z0-9]
- denotes values emitted from stream. |
- denotes completion of observable stream. #
- denotes error in observable stream. ()
- denotes grouping of values emitted on the same time frame. For your solution , hot('(a|'))
- means emit both the value a
and complete the observable stream within the same time frame.
References: https://github.com/jisaacks/RxJS/blob/master/doc/writing-marble-tests.md https://medium.com/@bencabanes/marble-testing-observable-introduction-1f5ad39231c
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.