0

New to react-router and having issues with Jest/Enzyme tests failing due to react-routers history prop.

The idea:

On submit of the form component call handleSubmit. handleSubmit calls validate to do some simple validation on the form. If validated history.push('/new-url-to-navigate-to') Else if not validated pushes error message to state.

The idea works when running the project - a valid form submit navigates to the /sent component, as expected.

So far so good.

The Issue

My issue comes from my jest/enzyme unit test to test whether the component renders an error message when the validation fails. The test code:

import React from 'react'
import { mount } from 'enzyme'
import { MemoryRouter } from 'react-router-dom'
import Form from '../Form'

describe('<Form />', () => {
  it('validates invalid form', () => {
    const component = mount(
      <MemoryRouter
        initialEntries={["/", "/form", "/saved"]}
        initialIndex={1}
      >
        <Form />
      </MemoryRouter>
    )
    const input = component.find('input')
    input.value = ""
    const form = component.find('form')

    form.simulate('submit', { preventDefault: () => {},
    target: {
      routingTextbox: input
    }});
    expect(component.find('h3').length).toBe(1)
  })
})

Which fails with:

<Form /> › validates invalid form

    TypeError: Cannot read property 'push' of undefined

      48 | 
      49 |     if (isValid) {
    > 50 |       history.push('/sent')

The error prevents the test from running and fails. If I remove/comment the history.push('/sent') line, the test passes, but I obviously need this line to navigate to the next page (as I say this works when running the project - it is just the test that is failing. I seem to not have access to the history prop in my component. Any help on how to move forward with this would be greatly appreciated.

Form component for reference

I don't think the issue is in here, since it's working perfectly when running the project, but would be happy to be proved wrong if I can get this test working!

// Form component
import React, { useState } from 'react';

const Form = ({ history }) => {

  const [state, setState] = useState({
    error: {
      isValid: true,
      message: ''
    }
  })

  const handleClick = () => {
    history.goBack()
  }

  const renderError = () => {
    if (state.error.isValid === false) {
      return(
        <div>
          <h3>{state.error.message}</h3>
        </div>
      )
    }

    return null
  }

  const validate = (value) => {
    if (value === "") {
      setState({
        error: {
          isValid: false,
          message: 'Please enter a value in the textbox'
        }
      })
      return false
    }

    return true
  }

  const handleSubmit = (e) => {
    e.preventDefault()
    const isValid = validate(e.target.routingTextbox.value)

    if (isValid) {
      history.push('/sent')
    } else {
      console.log('textbox is empty')
    }
  }

  return ( 
    <form onSubmit={handleSubmit}>
      <input type="text" name="routingTextbox" />
      <button type="submit">Submit</button>
      <button type="button" onClick={handleClick}>Go Back</button>
      {renderError()}
    </form>
  )
}

export default Form

Router for reference

const App = () => (
  <Router>
    <Switch>
      <Route path="/" exact component={Index} />
      <Route path="/form" component={Form} />
      <Route path="/sent" component={Sent} />
    </Switch>
  </Router>
)

export default App;
Mike Timms
  • 13
  • 3
  • Possible duplicate of [react-router " Cannot read property 'push' of undefined"](https://stackoverflow.com/questions/39184049/react-router-cannot-read-property-push-of-undefined) – Kiya Aug 14 '19 at 10:39
  • Nope, the component itself when running the server is accessing history prop fine. It is just the test that is failing. – Mike Timms Aug 14 '19 at 10:44

0 Answers0