Testeo de Componentes para Administradores en Platzi Orders

Clase 11 de 20Curso de React Testing Library

Contenido del curso

Resumen

Cuando una aplicación tiene secciones visibles solo para ciertos roles de usuario, es fundamental verificar que esos componentes se rendericen correctamente según los permisos. Aquí se aborda cómo testear un componente de resumen de órdenes que únicamente aparece para Super Admin, y cómo resolver conflictos cuando múltiples elementos comparten el mismo texto en el DOM.

¿Cómo se configura un test para un rol de Super Admin?

En el archivo de test del componente Orders, ya existía un caso de prueba previo configurado con el rol Visualizer. Para testear la sección exclusiva de administradores, se crea un nuevo caso de prueba con una variación clave: se envía el rol Super Admin al momento de renderizar el componente [01:05].

El flujo es el siguiente:

  • Se renderiza el componente Orders pasando el rol Super Admin.
  • Se ejecuta el mock de getOrders para retornar las órdenes simuladas.
  • Se utiliza waitFor junto con una función asíncrona, ya que el componente realiza operaciones que requieren esperar la resolución de datos.

El componente Orders internamente llama a Order Summary, que a su vez obtiene sus valores desde una utilidad llamada getSummaryOrders [02:00]. Esta función recibe un arreglo de órdenes y retorna de forma desestructurada el total de órdenes, el valor total y el promedio de ventas. En el test, se importa esta misma utilidad y se le pasan las mockOrders para obtener el valor esperado de totalOrders.

¿Qué hacer cuando getByText encuentra múltiples elementos?

Al intentar localizar el valor 1 con screen.getByText, el test falla porque existen múltiples elementos en el DOM con ese mismo contenido [03:15]. En una aplicación real, es muy común que un número como "1" aparezca en listas, contadores u otros lugares.

Aquí es donde entra getByTestId, una query de React Testing Library que funciona de manera similar a un ID en CSS: un elemento solo puede tener un identificador único. Para usarlo se necesitan dos pasos:

  • Modificar el componente: en la etiqueta <p> del Order Summary se agrega el atributo data-testid="Total Orders" [04:05].
  • Actualizar el test: se reemplaza getByText por getByTestId("Total Orders").

Con esto, el test busca exclusivamente el nodo que tiene ese data-testid, sin importar cuántos elementos compartan el mismo texto.

¿Cómo se extrae el texto correcto del elemento?

Al usar getByTestId, se obtiene el elemento HTML completo, no solo su contenido. Para acceder al texto se utiliza la propiedad .textContent [05:00]. Sin esta propiedad, el test compararía un objeto DOM contra un valor, lo cual siempre fallaría.

¿Cómo se resuelve la diferencia entre tipos number y string?

Otro error frecuente aparece cuando getSummaryOrders retorna un número, pero .textContent siempre devuelve un string [05:20]. La solución más directa es convertir totalOrders a string con String(totalOrders) antes de la comparación. El matcher también cambia: en lugar de toBeInTheDocument, se usa toBe para comparar el valor exacto del contenido.

El test final queda así:

javascript it('debería mostrar sección para Super Admins', async () => { handleRenderOrders('Super Admin'); mockGetOrders();

await waitFor(() => { const { totalOrders } = getSummaryOrders(mockOrders); const totalOrdersElement = screen.getByTestId('Total Orders'); expect(totalOrdersElement.textContent).toBe(String(totalOrders)); }); });

¿Cuándo es apropiado usar data-testid?

data-testid es un recurso de último nivel. Solo debe utilizarse cuando no existe otra forma de identificar un elemento en la vista, ya sea por texto, rol o etiqueta [05:50]. Abusar de este atributo puede llevar a tests frágiles que dependen de detalles de implementación en lugar del comportamiento real del componente.

Como práctica recomendada, intenta primero con queries como getByRole, getByText o getByLabelText. Si ninguna funciona por ambigüedad, entonces getByTestId es la alternativa correcta.

¿Ya probaste testear los valores restantes del resumen como el total de ventas y el promedio? Comparte tu solución en los comentarios.