How to test a search functionality property?

I have a search component that filters among fetched data. However, I see that it is always an empty string.
How can I test the updating and the display of the todos correctly?
here the code to be tested:

 const [todos, setTodos] = useState<Todos>({ all: [], searched: null });
 const [search, setSearch] = useState("");

 useEffect(() => {
   fetch("todos")
     .then((response) => {
       return response.json();
     })
     .then((response) => { 
       setTodos((todos) => ({ ...todos, all: response }));
     })
     .catch((e) => console.error(e));  
 }, []);
useEffect(()=>{ if (search) {
     setTodos((todos) => ({
       ...todos,
       searched: todos.all.filter((item) =>
         item.title.toLowerCase().includes(search.toLowerCase())
       ),
     }));
   }
 }, [search]);
 const handleOnChangeInput = (e: React.ChangeEvent<HTMLInputElement>) => {
   setSearch(e.target.value);
 };
<div className="search-container">
       <input
         className="search"
         value={search}
         onChange={handleOnChangeInput}
         placeholder="Search todo..."
         data-testid="search"
         type="text"
       />
       <button className="btn-delete" onClick={() => setSearch("")}>
         Clear search
       </button>
     </div>
     <div className="todos" data-testid="todos">
       {(todos.searched && todos.searched.length > 0
         ? todos.searched
         : todos.all
       ).map(({ id, title, completed }) => (
         <div
           data-testid="todo"
           key={id}
           className="todo"
           onClick={() => handleOnClickTodo(id)}
         >
           {completed ? <p className="tick">✅</p> : null}
           <p>{title}</p>
           <button
             className="btn-delete"
             onClick={(event) => handleOnClickDelete(event, id)}
           >
             Delete
           </button>
         </div>
       ))}
     </div>

Here is the test:

const mockResponse = [
   {
     userId: 1,
     id: 1,
     title: "Todo S",
     completed: false,
   },
   {
     userId: 1,
     id: 2,
     title: "Todo A",
     completed: true,
   },
 ];

 beforeEach(() => {
   jest.spyOn(global, "fetch" as any).mockResolvedValue({
     json: () => mockResponse,
   });
 });

 afterEach(() => {
   jest.restoreAllMocks();
 });
it("should filter todos based on search input", async () => {
   render(
     <MemoryRouter>
       <Home />
     </MemoryRouter>
   );
   const searchInput = screen.getByTestId("search");

   fireEvent.change(searchInput, {
     target: { value: "A" },
   });
   const todos = await screen.findAllByTestId("todo");
   expect(todos).toHaveLength(1);
 });

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.