React Testing Library and Redux Observable

You can use the test scheduler to test sequences in epics but integration testing breakdown if you don’t include redux observable in your test redux wrapper.

Here is how I successfully managed to integrate redux observable with react testing library by mocking out the store. This wrapper replaces the default react-testing-library render method with a render method that gives components access to redux, react-router and redux observable in a test environment.

import React from 'react';
import { render as rtlRender } from '@testing-library/react';
import { Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import { createEpicMiddleware } from 'redux-observable';
import { rootReducer, rootEpic, dependencies } from './store';

function configureStore(initialState) {
  const epicMiddleware = createEpicMiddleware({ dependencies });

  const store = createStore(

  return store;

export const render = (
    route = '/',
    history = createMemoryHistory({ initialEntries: [route] }),
    store = configureStore(initialState),
  } = {}
) => ({
    <Provider store={store}>
      <Router history={history}>{ui}</Router>

// adding `history and store` to the returned utilities to allow you to reference it in our tests (just try to avoid using this to test implementation details).

Then to run an integration test you mock out the dependency you intend to test.

import { exampleMethod } from '../exampleAPI';

jest.mock('../exampleAPI', () => ({
  exampleMethod: jest.fn(),

Then you can just write an integration test that fires the epic and asserts that the dependency was called with the correct values.

it('tests exampleMethod runs when example epic is called ', 
async () => {
      const { getByTestId, getByPlaceholderText } = render(
        <ExampleComponent />,
          initialState: {
            user: {
              userId: '123',

      userEvent.type(getByPlaceholderText('Their name...'), 'Mr. Happy');
      await wait(() => {
        expect(exampleMethod).toHaveBeenCalledWith('123', {
          name: 'Mr. Happy',

Now read this

Information Onslaught

There are physical limitations to how much I can learn in one go. My brain just fizzles out and the simplest things stop making sense. The first week at Founders and Coders has been intense. The cohort was split into groups of four and... Continue →