I am trying to test that an @Effect({ dispatch: false }) is calling a trackEvent() method, but the effect does not raise any further action so it is not possible to subscribe to the effects observable as described in the docs.
My effect looks like this:
@Effect({ dispatch: false })
public trackPageView$: Observable<any> = this.action$
.ofType(ActionTypes.TRACK_PAGE_VIEW)
.map((action: TrackPageViewAction) => {
this.angulartics2Service.trackPageView(action.payload.path);
});
...and an extract of my spec looks like this:
it(`should call #trackPageView('${testPath}')`, () => {
runner.queue(trackPageView(testPath));
let s = TestBed.get(Angulartics2Service);
expect(s.trackPageView.called).toBeTruthy(); // <-- fails!
});
My angulartics2Service looks like this:
let angulartics2Service: Stubbed<Angulartics2Service>;
angulartics2Service = {
trackPageView: sinon.stub()
}
...where
export type Stubbed<T> = {
[key in keyof T]?: T[key] & SinonStub;
};
How do I test this effect is calling trackPageView() method?
Any help appreciated.
Coming into this a little late, but I ran into this same problem and ended up here. Let's say I'm testing the following effects:
@Effect()
onPlaceOrder$ : Observable<any> = this.actions$.pipe(
ofType(CheckoutActionTypes.PlaceOrderAction),
map(() => new PlaceOrderSuccess())
);
@Effect({ dispatch: false })
onPlaceOrderSuccess$ : Observable<any> = this.actions$.pipe(
ofType(CheckoutActionTypes.PlaceOrderSuccessAction),
tap(() => {
this.router.navigateByUrl('/checkout/thank-you');
})
);
This is how I ended up testing them:
describe('when PlaceOrderAction is triggered', () => {
let expected;
const placeOrderAction = new PlaceOrder();
beforeEach(() => {
const placeOrderSuccessAction = new PlaceOrderSuccess();
actions$ = hot('--a', { a: placeOrderAction });
expected = cold('--b', { b: placeOrderSuccessAction });
});
it('should dispatch a PlaceOrderSuccess action', () => {
expect(effects.onPlaceOrder$).toBeObservable(expected);
});
});
describe('when PlaceOrderSuccessAction is triggered', () => {
let expected;
const placeOrderSuccessAction = new PlaceOrderSuccess();
beforeEach(() => {
actions$ = hot('--a', { a: placeOrderSuccessAction });
expected = cold('--b', { b: placeOrderSuccessAction });
});
it('should call router.navigateByUrl', () => {
//the actual effect doesn't trigger unless the following expect is run
expect(effects.onPlaceOrderSuccess$).toBeObservable(expected);
expect(router.navigateByUrl).toHaveBeenCalledWith('/checkout/thank-you');
});
});
I'm using jasmine marbles for testing by the way: https://github.com/synapse-wireless-labs/jasmine-marbles
I needed to trigger the onPlaceOrderSuccess effect by calling that first expect block (expect(effects.onPlaceOrderSuccess$).toBeObservable(expected);) in order to get the effect to run. Then it turned out that the returned value of a dispatch: false effect is actually the original action. So that's how you can test that your trackPageView() method is called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With