Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test a react event handler that contains history.push using Jest and Enzyme?

Given a simple component:

export default class SearchForm extends Component {
  constructor(props) {
    super(props)
    this.state = { query: '' }
  }
  onSubmit = (event) => {
    event.preventDefault()
    history.push(`/results/${this.state.query}`, { query: this.state.query })
  }
  render() {
    return (
      <form onSubmit={this.onSubmit}>
        <input
          type="text"
          value={this.state.query}
          onChange={event => this.setState({ query: event.target.value })}
        />
        <button>Search</button>
      </form>
    )
  }
}

And the test:

describe('SearchForm Component', () => {
  it('should navigate to results/query when submitted', () => {
    const wrapper = shallow(<SearchForm />)
    ...?
  })
})

How do you verify that form submission is taking the user to the next page with the correct query value?

I've tried simply mocking the onSubmit handler and at least confirming that it's been called, but this results in a security error due to history.push.

const wrapper = shallow(<SearchForm />)
const mockedEvent = { target: {}, preventDefault: () => {} }
const spy = jest.spyOn(wrapper.instance(), 'onSubmit')
wrapper.find('form').simulate('submit', mockedEvent)
expect(spy).toHaveBeenCalled()
like image 273
Darryl Snow Avatar asked Jun 04 '18 14:06

Darryl Snow


People also ask

How do you mock history in Jest?

push with the new React Router Hooks using Jest, we can call jest. mock to mock the useHistory hook. import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import { render, fireEvent } from '@testing-library/react'; import RouteNotFound from './NotFound'; const mockHistoryPush = jest. fn(); jest.

How do you test for Jest and enzymes?

Both Jest and Enzyme are meant to test the react applications. Jest can be used with any other Javascript framework, but Enzyme is meant to run on react only. Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it.

What is difference between Jest and Enzyme and React testing library?

Jest is a test framework that has a runner and assertions. Enzyme is a test util library for manipulating and asserting React components, it works with Jest or Karma or Mocha or other test frameworks. Karma and Jasmine would be an alternative to Jest.


1 Answers

It's actually simple, you can pass in any props to the component when shallow rendering it inside the test, like that:
const wrapper = shallow(<SearchForm history={historyMock} />)

By the way, inside onSubmit, you should call like this.props.history.push(...).

Now, to create a mock (more info in the documentation), you can write like this in the test:
const historyMock = { push: jest.fn() };

Keep in mind that you are actually mocking only the push method of the history object, if you use more methods inside the component and want to test them, you should create a mock to each one tested.

And then, you need to assert that the push mock was called correctly. To do that, you write the assertion necessary:
expect(historyMock.push.mock.calls[0]).toEqual([ (url string), (state object) ]);
Use the needed (url string) and (state object) to be asserted.

like image 129
rodgobbi Avatar answered Oct 13 '22 02:10

rodgobbi