Tengo un componente TodoList simple que usa un enlace personalizado useTodos
import { useState } from 'react' export const useTodos = (initialTodos = []) => { const [todos, setTodos] = useState(initialTodos) const addTodo = (value) => { const updatedTodos = [...todos, value] setTodos(updatedTodos) } const removeTodo = (index) => { const updatedTodos = todos.filter((todo, i) => i !== index) setTodos(updatedTodos) } return { todos, addTodo, removeTodo } } Me gustaría probar el componente con React Testing Library .
Para hacerlo, quiero burlarme de los todos iniciales devueltos por el gancho.
jest.mock('hooks/useTodos', () => ({ useTodos: () => ({ todos: ['Wake up', 'Go to work'], }), })) Pero los métodos addTodo y removeTodo no están definidos. Por otro lado, cuando me burlo de ellos con jest.fn() ya no funcionan.
¿Hay alguna forma de burlarse solo de todos y mantener otros métodos funcionando ?
Puede crear un gancho useTodos simulado con un estado inicial de todos simulado basado en el gancho useTodos real.
hooks.js :
import { useState } from 'react'; export const useTodos = (initialTodos = []) => { const [todos, setTodos] = useState(initialTodos); const addTodo = (value) => { const updatedTodos = [...todos, value]; setTodos(updatedTodos); }; const removeTodo = (index) => { const updatedTodos = todos.filter((todo, i) => i !== index); setTodos(updatedTodos); }; return { todos, addTodo, removeTodo }; }; index.jsx :
import React from 'react'; import { useTodos } from './hooks'; export default function MyComponent() { const { todos, addTodo, removeTodo } = useTodos(); return ( <div> {todos.map((todo, i) => ( <p key={i}> {todo} <button type="button" onClick={() => removeTodo(i)}> Remove </button> </p> ))} <button type="button" onClick={() => addTodo('have a drink')}> Add </button> </div> ); } index.test.jsx :
import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; import MyComponent from '.'; jest.mock('./hooks', () => { const { useTodos } = jest.requireActual('./hooks'); return { useTodos: () => useTodos(['Wake up', 'Go to work']), }; }); describe('69399677', () => { test('should render todos', () => { render(<MyComponent />); expect(screen.getByText(/Wake up/)).toBeInTheDocument(); expect(screen.getByText(/Go to work/)).toBeInTheDocument(); }); test('should add todo', () => { render(<MyComponent />); fireEvent.click(screen.getByText(/Add/)); expect(screen.getByText(/have a drink/)).toBeInTheDocument(); }); test('should remove todo', () => { render(<MyComponent />); fireEvent.click(screen.getByText(/Go to work/).querySelector('button')); expect(screen.queryByText(/Go to work/)).not.toBeInTheDocument(); }); });resultado de la prueba:
PASS examples/69399677/index.test.jsx (8.788 s) 69399677 ✓ should render todos (26 ms) ✓ should add todo (10 ms) ✓ should remove todo (4 ms) -----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -----------|---------|----------|---------|---------|------------------- All files | 100 | 0 | 100 | 100 | hooks.js | 100 | 0 | 100 | 100 | 3 index.jsx | 100 | 100 | 100 | 100 | -----------|---------|----------|---------|---------|------------------- Test Suites: 1 passed, 1 total Tests: 3 passed, 3 total Snapshots: 0 total Time: 9.406 s