Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock browserHistory in unit test environment?

I'm trying to test React component which uses browserHistory of react-router. To ensure access to browserHistory I'm using createMemoryHistory (react-router) module like this:

let createMemoryHistory = require('react-router/lib/createMemoryHistory');

In test env I'm taking advantage of JSDOM library.

global.document = jsdom('');
global.window = document.defaultView;

Then I'm trying to assign created history object to DOM:

let history = createMemoryHistory();
global.history = history;

While rendering component in test environment, I'm getting following error:

Invariant Violation: Browser history needs a DOM

Any idea how to overcome it?

like image 704
magos Avatar asked Aug 16 '16 13:08

magos


3 Answers

The other answers are great, but they didn't work for my use case where I was simulating a button click which called browserHistory.push('/myroute').

In my case it was much easier to mock browserHistory in my test file using jest:

import { browserHistory } from 'react-router';

jest.mock('react-router', () => ({
  browserHistory: {
    push: jest.fn(),
  },
}));

...

it('pushes to browserHistory', () => {

    const renderedComponent = shallow(<Component />);

    <<< insert whatever you need to simulate the event that pushes to browserHistory >>>
    const button = renderedComponent.find('.btn');
    button.simulate('click');

    expect(browserHistory.push).toHaveBeenCalledTimes(1);
})
...
like image 112
Emily Collins Nielsen Avatar answered Nov 13 '22 21:11

Emily Collins Nielsen


You need to mock the browserHistory object. You can use sinon to create spies or stubs to help you test this.

For example:

With spy

const { createBrowserHistory } =  require('history');

const history = createBrowserHistory(/* ... */);

sinon.spy(history, "push");

// now you should be able to run assertions on history.push

assert(history.push.calledOnce)

More on the spy and stub

http://sinonjs.org/releases/v4.1.6/spies/

http://sinonjs.org/releases/v4.1.6/stubs/

like image 29
Waseem Avatar answered Nov 13 '22 20:11

Waseem


You can do it with jest as well:

const { createBrowserHistory } =  require('history');
const history = createBrowserHistory(/* ... */);
jest.spyOn(history, "push");

// now you should be able to run assertions on history.push
assert(history.push.calledOnce)
like image 2
Dennis T Avatar answered Nov 13 '22 22:11

Dennis T