0
votes

I'm trying to do jest+enzyme tests with my react app but i'm getting an error at the route component. I'm using router v4.

I did try to use MemoryRouter Wrapper to the shallow component, or use mount instead of shallow. Everything didn't work.

My test:

describe('Movie Page tests', () => {
    const wrapper =  shallow(<Movie />).toJSON()

    it('should call Movie snapshot correctly', () => {
        const tree = renderer
            .create(wrapper)
            .toJSON();
        expect(tree).toMatchSnapshot();
        });
})

Full component:

export const Movie = ({
   match, 
   searchMovieAction,
   movies,
   totalResults,
   pending,
   error,
  }, props) => {
    const [ showModal, setShowModal ] = useState(false);

    //const { searchMovieAction } = useActions();
    const { values, handleInputChange } = useFormInput({
      searchValue: '', 
    });

    console.log('PROPES ------>', error,);

    /* const {
        movie: {
          movie,
          totalResults,
          pending,
          error,
        },
    } = useSelector(state => state); */

    const handleSubmit = (e) => {
      e.preventDefault()
      const { searchValue } = values;

      if(searchValue) {
        searchMovieAction(searchValue);
      }

    }

    const toggleModal = () => {
      setShowModal(!showModal);
    }

    return (
        <div className='movies'>
            <div>
              <StyledForm onSubmit={handleSubmit}>
                <DefaultInput 
                    name='searchValue' 
                    value={values.searchValue}
                    placeholder='Search a movie...'
                    handleChange={handleInputChange} 
                  />
                <Button solid rounded right >Search</Button>
              </StyledForm>
            </div>

            { pending && <LoadingSpinner medium />}

            { error && <Error message={error} /> }

            { movies && movies.length > 0 && !pending && !error && (
              <p>
                We found <strong>{ totalResults }</strong>
                {totalResults == 1 ? 'result!' : ' results!'}
              </p>
            )}

            <StyledMovies>

              {movies && movies.map((m) => {
                  const { Title, Poster, Plot, imdbID } = m

                  return(
                    <StyledMovieItem key={uniqueId()}>
                      <Link to={`${match.url}/${imdbID}`} onClick={setShowModal}>
                        <MovieSummary data={{Title, Poster, Plot}} />
                      </Link>

                    </StyledMovieItem>
                  )
                })
              }
              <Modal handleClose={toggleModal} show={showModal}>
                <Route
                  exact
                  path={`${ match.path }/:imdbID`}
                  render={(props) => <MovieDetail {...props} /> }
                />
              </Modal>
            </StyledMovies>
        </div>
    )

}

The error:

TypeError: Cannot read property 'path' of undefined

 99 |                 <Route
 100 |                   exact
101 |                   path={`${ match.path }/:imdbID`}
     |                                   ^
 102 |                   rende

The application is working, but at the test the match param is empty. Does someone knows what can be?

2

2 Answers

0
votes

You need to wrap your component into any <MemoryRouter> and <Router> like

const wrapper =  shallow(<MemoryRouter><Route component={Movie} /></MemoryRouter>).dive().dive()

dive() is needed because otherwise only <MemoryRouter> itself is rendered by shallow().

See article with more detailed explanation: https://medium.com/@antonybudianto/react-router-testing-with-jest-and-enzyme-17294fefd303

0
votes

If you don't want to wrap your component with a router in your tests, you can mock match like any other props:

const mockMatch = {
  path: 'my-path/some-value',
  url: 'my-path/some-value'
}
const wrapper =  shallow(<Movie match={mockMatch}/>).toJSON()