Consider this angular component:
export class CheckoutComponent {
constructor(private paymentService: PaymentService, private paymentModalService: PaymentModalService) {}
public onCheckout(): void {
const paymentStatus$: Observable<string> = this.paymentService.getStatus();
const paymentRequired$ = paymentStatus$.pipe(map(paymentStatus => paymentStatus === 'INCOMPLETE'));
paymentRequired$.subscribe(() => {
this.paymentModalService.open();
});
}
}
I'm trying to write a jasmine test to confirm that paymentModalService.open()
was called:
import { cold } from 'jasmine-marbles';
describe('CheckoutComponent', () => {
let component: CheckoutComponent;
let mockPaymentService: jasmine.SpyObj<PaymentService>;
let mockPaymentModalService: jasmine.SpyObj<PaymentModalService>;
beforeEach(() => {
mockPaymentService = jasmine.createSpyObj(['getStatus']);
mockPaymentModalService = jasmine.createSpyObj(['open']);
component = new CheckoutComponent(mockPaymentService, mockPaymentModalService);
});
it('should open payment modal if required', () => {
mockPaymentService.getStatus.and.returnValue(cold('a', { a: 'INCOMPLETE' }));
component.onCheckout();
expect(mockPaymentModalService.open).toHaveBeenCalled(); // FAIL: was never called
});
});
However the open method was apparently never called.
Is there any way to wait for the cold test observable to complete emit before asserting that the method has been called?
I've tried using fakeAsync
and tick
but it does not either seem to help. I realize it works with of()
instead of a TestColdObservable
, but I would like more granular control of observable behavior. I don't really intend to complete the getStatus()
observable.
Reading documentation on component marble tests I found that I need to flush the test scheduler like so: