问题
I'm creating some unit tests for an Angular application that I have. I have managed to test services that make HTTP calls without any problems. I now moved to a different kind of service, which is shown below.
Code
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { UICoupon } from '../models';
@Injectable()
export class ClaimCouponService {
hasClaimedCoupons = false;
claimedCoupons: UICoupon[] = [];
onClaimCoupons: Observable<UICoupon[]>;
private couponsUpdate: Subject<UICoupon[]> = new Subject<UICoupon[]>();
constructor() {
this.onClaimCoupons = this.couponsUpdate.asObservable();
}
claimCoupon(coupon: UICoupon) {
if (!coupon.claimed) {
coupon.claimed = true;
this.claimedCoupons.push(coupon);
}
this.hasClaimedCoupons = true;
this.couponsUpdate.next(this.claimedCoupons);
}
}
I have managed to test the logic for this service using the "Subscribe / Assert pattern". Using the below code:
...
it('should claim a coupon', (done) => {
claimCouponsService.onClaimCoupons
.subscribe(claimedCoupons => {
expect(claimedCoupons).toEqual([mockData[0]]);
done();
});
claimCouponsService.claimCoupon(mockData[0]);
});
The above works well, however I was researching and I was curious about Marble Testing. I've read a few articles and I like how the logic is structured in the test. I've tried to replicate the above test with Marble Testing, but in my case I couldn't find a way to verify what is emitted from the service after the claimCoupon(...)
function is run.
let scheduler: TestScheduler;
let claimCouponsService: ClaimCouponsService;
...
it('should claim a coupon', (done) => {
const expectedObservable = claimCouponsService.onClaimCoupons;
scheduler.run(runHelpers => {
claimCouponsService.claimCoupon(mockData[0]);
const expectedMarble = '^a|';
const expectedData = { a: [mockData[0]] };
runHelpers.expectObservable(expectedObservable)
.toBe(expectedMarble, expectedData);
});
});
I'm pretty sure that this is possible, but I have some kind of mistake in my test - or haven't really understood the way marble testing works. The above results in an error Expected $.length = 0 to equal 1.
which I think means that the observable didn't get any values. I know the test I wrote does run successfully, however I'm curious to see how Marble Testing can be used.
来源:https://stackoverflow.com/questions/60817058/angular-unit-testing-verify-emitted-value-from-an-observable-using-marble-test