act es un auxiliar de pruebas para aplicar actualizaciones pendientes de React antes de realizar aserciones.
await act(async actFn)Para preparar un componente para las aserciones, envuelve el código que lo renderiza y realiza actualizaciones dentro de una llamada a await act(). Esto hace que tu prueba se ejecute de forma más parecida a cómo funciona React en el navegador.
Referencia
await act(async actFn)
Al escribir pruebas de UI, tareas como el renderizado, eventos del usuario o la obtención de datos pueden considerarse como “unidades” de interacción con una interfaz de usuario. React proporciona un auxiliar llamado act() que se asegura de que todas las actualizaciones relacionadas con estas “unidades” hayan sido procesadas y aplicadas al DOM antes de realizar cualquier aserción.
El nombre act proviene del patrón Arrange-Act-Assert (Organizar-Actuar-Afirmar).
it ('renders with button disabled', async () => {
await act(async () => {
root.render(<TestComponent />)
});
expect(container.querySelector('button')).toBeDisabled();
});Parámetros
async actFn: Una función asíncrona que envuelve renderizados o interacciones para los componentes que se están probando. Cualquier actualización disparada dentro deactFnse agrega a una cola interna de act, que luego se procesan juntas para aplicar cualquier cambio al DOM. Dado que es asíncrona, React también ejecutará cualquier código que cruce un límite asíncrono y vaciará cualquier actualización programada.
Retorno
act no devuelve nada.
Uso
Al probar un componente, puedes usar act para realizar aserciones sobre su salida.
Por ejemplo, supongamos que tenemos este componente Counter, los ejemplos de uso a continuación muestran cómo probarlo:
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(prev => prev + 1);
}
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleClick}>
Click me
</button>
</div>
)
}Renderizar componentes en pruebas
Para probar la salida del renderizado de un componente, envuelve el renderizado dentro de act():
import {act} from 'react';
import ReactDOMClient from 'react-dom/client';
import Counter from './Counter';
it('can render and update a counter', async () => {
container = document.createElement('div');
document.body.appendChild(container);
// ✅ Renderiza el componente dentro de act().
await act(() => {
ReactDOMClient.createRoot(container).render(<Counter />);
});
const button = container.querySelector('button');
const label = container.querySelector('p');
expect(label.textContent).toBe('You clicked 0 times');
expect(document.title).toBe('You clicked 0 times');
});Aquí, creamos un contenedor, lo añadimos al documento y renderizamos el componente Counter dentro de act(). Esto asegura que el componente se renderice y sus efectos se apliquen antes de realizar las aserciones.
Usar act asegura que todas las actualizaciones se hayan aplicado antes de realizar las aserciones.
Despachar eventos en pruebas
Para probar eventos, envuelve el despacho del evento dentro de act():
import {act} from 'react';
import ReactDOMClient from 'react-dom/client';
import Counter from './Counter';
it.only('can render and update a counter', async () => {
const container = document.createElement('div');
document.body.appendChild(container);
await act( async () => {
ReactDOMClient.createRoot(container).render(<Counter />);
});
// ✅ Despacha el evento dentro de act().
await act(async () => {
button.dispatchEvent(new MouseEvent('click', { bubbles: true }));
});
const button = container.querySelector('button');
const label = container.querySelector('p');
expect(label.textContent).toBe('You clicked 1 times');
expect(document.title).toBe('You clicked 1 times');
});Aquí, renderizamos el componente con act y luego despachamos el evento dentro de otro act(). Esto asegura que todas las actualizaciones del evento se apliquen antes de realizar las aserciones.
Solución de problemas
Recibo un error: “The current testing environment is not configured to support act”(…)”
Usar act requiere configurar global.IS_REACT_ACT_ENVIRONMENT=true en tu entorno de pruebas. Esto es para asegurar que act solo se use en el entorno correcto.
Si no configuras la variable global, verás un error como este:
Para solucionarlo, añade esto a tu archivo de configuración global para las pruebas de React:
global.IS_REACT_ACT_ENVIRONMENT=true