Pruebas

Los componentes y los culets son funciones simples, así que ambos se pueden probar directamente. No hace falta entorno de DOM ni biblioteca de renderizado.

Configuración

El script de pruebas ejecuta Vitest con cobertura de V8. Excluye de la cobertura los puntos de entrada, el archivo de facetas y la carpeta DTO, porque son cableado, no lógica.

// vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    coverage: {
      reporter: [
        "text",
        "html",
        "lcov"
      ],
      include: ['src/**/*.{ts,tsx}'],
      exclude: [
        'src/client/entrypoint.ts',
        'src/server/entrypoint.ts',
        'src/client/facets.cara.ts',
        'src/infra/**/*',
        'src/dto/**/*',
        '**/*.d.ts',
      ],
    },
  },
});

Probar un componente

Llama una vez a init desde jjsx para instalar el transpilador y luego llama a transpile con un elemento JSX para obtener la cadena HTML. Afirmar sobre subcadenas de esa cadena suele bastar y mantiene la prueba libre de DOM.

// src/client/__tests__/profile-page.test.tsx
import { expect, test } from "vitest";
import { init, transpile } from "jjsx";
import Profile from "../pages/profile";

init();

test("Render profile page", () => {
    const mockUser = {
        id: "1",
        name: "John Doe",
        email: "john@example.com",
        username: "johndoe",
        phone: "123-456-7890",
        website: "johndoe.com",
    };

    const page = transpile(<Profile {...mockUser} />);

    expect(page).toContain('app-header');
    expect(page).toContain("John Doe");
    expect(page).toContain("john@example.com");
    expect(page).toContain("Vault Member");
});

Un componente bruñido acepta sus props del servidor como props corrientes, así que el mismo elemento se renderiza con datos simulados en una prueba exactamente igual que en el servidor.

init() instala el transpilador de JJSX y debe ejecutarse antes de la primera llamada a transpile. Como el resultado es una cadena HTML simple, no hay DOM que preparar ni biblioteca de renderizado que configurar.

Probar un culet

Un culet es una función que va de una petición a un valor. Pásale un objeto simple con params y llámala. No hay ningún servidor que arrancar, que es la razón principal por la que los culets son baratos de probar.

// src/server/__tests__/trade-api.test.ts
import { describe, expect, test } from "vitest";
import getTradeData from "../culets/trade";

describe("Trade API", () => {
    test("GET /trade/btc", async () => {
        const mockRequest = {
            params: { symbol: "btc" },
            url: "/trade/btc",
            query: {},
            headers: {},
            cookies: {},
            method: "GET",
        };
        const result = await getTradeData(mockRequest);
        expect(result.symbol).toBe("BTC");
        expect(result.price).toBeDefined();
        expect(result.orderBook.bids.length).toBeGreaterThan(0);
    });
});

@fetch-mock/vitest está disponible para un culet que llame a una API remota, lo que mantiene la prueba sin conexión y determinista.

Cobertura

Un componente que lea window o document directamente en su cuerpo no se puede transpilar en una prueba, porque el entorno de pruebas no tiene documento. Eso es una señal útil y no un obstáculo: significa que el efecto secundario pertenece a una llamada afterMount o beforeMount, donde el framework ya lo mantiene fuera del renderizado del servidor.