react test with useEffect, axios and useParams

42 Views Asked by At
...

const MovieDetails = () => {
  ...

  let { movieId } = useParams();
  const [movie, setMovie] = useState(null);
  
  useEffect(() => {
    // axios settings
    let unmounted = false;
    let source = axios.CancelToken.source();
    axios.get(`http://localhost:4000/movies/${movieId}`, {
      cancelToken: source.token
    }).then(result => {
      if (!unmounted) {
        setMovie(result.data)
      }
    }).catch(function (e) {
      if (!unmounted) {
        if (axios.isCancel(e)) {
          console.log(`request cancelled:${e.message}`);
        } else {
          console.log("another error happened:" + e.message);
        }
      }
    });
    return function () {
      unmounted = true;
      source.cancel("Cancelling in cleanup");
    };
  }, [movieId]);

  return (
    <div className={styles.movieDetail}>
      {movie && (
...

export default MovieDetails;

How can I write a unit test for this code above?

It includes axios, useEffect and useParams.

Basically, I am listing movies and it is showing movie details on click.

My test is looking like this for now:

It is failing on render part because somehow I have to use useParams with axios

...

describe('MovieDetails', () => {
  let testList = movieList;

  test('render movie details when a movie is selected', () => {
    render(
      <MemoryRouter>
        <MovieDetails />
      </MemoryRouter>
    );
    const element = screen.getByTestId('movieDetails');
    expect(element).toBeInTheDocument();
    const image = element.querySelector("img");
...

export default MovieDetails;
1

There are 1 best solutions below

0
Drew Reese On BEST ANSWER

You are on the right track using the MemoryRouter, but you'll also need to render MovieDetails on a route with a path that has a movieId parameter.

Example:

import {
  MemoryRouter,
  Routes,
  Route,
} from 'react-router-dom';

test('render movie details when a movie is selected', () => {
  render(
    <MemoryRouter initialEntries={["/movies/1234"]}>
      <Routes>
        <Route
          path="/movies/:movieId"
          element={<MovieDetails />}
        />
      </Routes>
    </MemoryRouter>
  );

  ...
};