title: How to correctly test effects in ngrx 4?
body: <p>There are plenty of tutorials how to <strong>test effects</strong> in <strong>ngrx 3</strong>.</p>
  
  <p>However, I've found only 1 or 2 for <em>ngrx4</em> (where they removed the classical approach via <strong>EffectsTestingModule</strong> ), e.g. <a href="https://github.com/ngrx/platform/blob/master/docs/effects/testing.md" rel="nofollow noreferrer">the official tutorial</a></p>
  
  <p>However, in my case their approach doesn't work.</p>
  
  <p><strong>effects.spec.ts</strong> (under <em>src/modules/list/store/list</em> in the link below)</p>
  
  <pre><code> describe('addItem$', () =&gt; {
      it('should return LoadItemsSuccess action for each item', async() =&gt; {
        const item = makeItem(Faker.random.word);
        actions = hot('--a-', { a: new AddItem({ item })});
  
        const expected = cold('--b', { b: new AddUpdateItemSuccess({ item }) });
        // comparing marbles
        expect(effects.addItem$).toBeObservable(expected);
      });
    })
  </code></pre>
  
  <p><strong>effects.ts</strong> (under <em>src/modules/list/store/list</em> in the link below)</p>
  
  <pre><code>...
   @Effect() addItem$ = this._actions$
      .ofType(ADD_ITEM)
      .map&lt;AddItem, {item: Item}&gt;(action =&gt; {
        return action.payload
      })
      .mergeMap&lt;{item: Item}, Observable&lt;Item&gt;&gt;(payload =&gt; {
        return Observable.fromPromise(this._listService.add(payload.item))
      })
      .map&lt;any, AddUpdateItemSuccess&gt;(item =&gt; {
        return new AddUpdateItemSuccess({
          item,
        })
      });
  ...
  </code></pre>
  
  <p><strong>Error</strong></p>
  
  <pre><code> should return LoadItemsSuccess action for each item
          Expected $.length = 0 to equal 1.
          Expected $[0] = undefined to equal Object({ frame: 20, notification: Notification({ kind: 'N', value: AddUpdateItemSuccess({ payload: Object({ item: Object({ title: Function }) }), type: 'ADD_UPDATE_ITEM_SUCCESS' }), error: undefined, hasValue: true }) }).
              at compare (webpack:///node_modules/jasmine-marbles/index.js:82:0 &lt;- karma-test-shim.js:159059:33)
              at Object.&lt;anonymous&gt; (webpack:///src/modules/list/store/list/effects.spec.ts:58:31 &lt;- karma-test-shim.js:131230:42)
              at step (karma-test-shim.js:131170:23)
  </code></pre>
  
  <p>NOTE: the effects use a <strong>service</strong> which involves writing to PouchDB. However, the issue doesn't seem related to that
   and also <strong>the effects work</strong> in the running app.</p>
  
  <p>The full code is a Ionic 3 app and be found <a href="https://github.com/dragGH102/ionic-with-ngrx-and-multiple-modules" rel="nofollow noreferrer">here</a> (just clone, npm i and <strong>npm run test</strong>)</p>
  
  <p><strong>UPDATE</strong>: </p>
  
  <p>With <strong>ReplaySubject</strong> it works, but not with hot/cold marbles</p>
  
  <pre><code>  const item = makeItem(Faker.random.word);
    actions = new ReplaySubject(1) // = Observable + Observer, 1 = buffer size
  
    actions.next(new AddItem({ item }));
  
    effects.addItem$.subscribe(result =&gt; {
      expect(result).toEqual(new AddUpdateItemSuccess({ item }));
    });
  </code></pre>