My tests are passing fine - but I still get the (in)famous *Warning: An update to Movie inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */*
here:
13 | 14 | const handleSelect = () => {
15 | setSelected(!selected); | ^ 16 | }; 17 | 18 | return (
I can't figure how to solve it.
My code below
Movies.tsx
import { useState } from "react";
import { MovieSearchResults } from "../../model/movie";
import Movie from "../Movie/Movie";
import Search from "../Search/Search";
import Pager from "../Pager/Pager";
import "./Movies.css";
const Movies = () => {
const [search, setSearch] = useState<string>("");
const [movies, setMovies] = useState<MovieSearchResults>({
results: [],
total_pages: 1,
page: 1,
});
const handleSearch = () => {
fetch(
`https://api.themoviedb.org/3/search/movie?api_key=${process.env.REACT_APP_API_KEY}&query=${search}`
)
.then((response) => response.json())
.then((json) => setMovies(json));
};
const handlePager = (page: number) => {
fetch(
`https://api.themoviedb.org/3/search/movie?api_key=${process.env.REACT_APP_API_KEY}&query=${search}&page=${page}`
)
.then((response) => response.json())
.then((json) => setMovies(json));
};
return (
<div className="Movies">
<Search search={search} setSearch={setSearch} onSearch={handleSearch} />
{movies && movies.total_pages > 1 ? (
<Pager
{...movies}
total_pages={movies.total_pages}
onPageChange={handlePager}
/>
) : (
<></>
)}
{movies &&
movies.results.map((movie) => (
<Movie
{...movie} /*here I am destructuring movie properties because I don't need to specify all*/
id={movie.id}
poster_path={movie.poster_path}
title={movie.title}
key={movie.id}
overview={movie.overview.substring(0, 250) + "..."}
/>
))}
{movies && movies.total_pages > 1 ? (
<Pager
{...movies}
total_pages={movies.total_pages}
onPageChange={handlePager}
/>
) : (
<div className="message--noResulst">
Sorry. There's no results available for your search...
</div>
)}
</div>
);
};
export default Movies;
Movie.tsx
import { useState } from "react";
import { MovieSearchResult } from "../../model/movie";
import classnames from "classnames";
import "./Movie.css";
const Movie = (movie: MovieSearchResult, key: number) => {
//select Movie on click:
const [selected, setSelected] = useState<boolean>(false);
// use classnames to modify className on select:
const classNames = classnames("Movie", { Movie__selected: selected });
const handleSelect = () => {
setSelected(!selected);
};
return (
<div className={classNames} onClick={handleSelect}>
<div className="Movie__poster-wrap">
<img
className="Movie__poster"
src={`https://image.tmdb.org/t/p/w92${movie.poster_path}`}
alt="Movie poster"
/>
</div>
<div className="Movie__details">
<h2>{movie.title}</h2>
<p>{movie.overview}</p>
</div>
</div>
);
};
export default Movie;
Movie.test.js
import React from "react";
import renderer from "react-test-renderer";
import { act, render, fireEvent } from "@testing-library/react";
import Movie from "./Movie";
describe("Movie", () => {
it(" changes the class of Movie when clicked i.e. selected", async () => {
const movie = {
adult: false,
backdrop_path: "/eM9MZ1dhDCbRzwQg0FWpWWtLPMn.jpg",
genre_ids: [10752, 28, 18],
id: 390054,
original_language: "en",
original_title: "Sand Castle",
overview:
"Set during the occupation of Iraq, a squad of U.S. soldiers try to protect a small village....",
popularity: 38.305,
poster_path: "/c9buG2jVRgAu68E4D4jpwlgqhO1.jpg",
release_date: "2017-04-21",
title: "Sand Castle",
video: false,
vote_average: 6.5,
vote_count: 613,
};
const component = renderer.create(
<Movie
{...movie}
id={movie.id}
poster_path={movie.poster_path}
title={movie.title}
key={movie.id}
overview={movie.overview.substring(0, 250) + "..."}
/>
);
let tree = component.toJSON();
expect(tree).toMatchSnapshot();
//trigger the click
tree.props.onClick();
// re-rendering
tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});
I've looked into the act(...) functionality on Jets but couldn't figure it out.
Thanks in advance for the help and explanations