Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing @Effect when dispatch:false

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.

like image 338
serlingpa Avatar asked Aug 22 '26 01:08

serlingpa


1 Answers

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.

like image 160
lderrickable Avatar answered Aug 24 '26 14:08

lderrickable



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!