En el ecosistema moderno del desarrollo backend, el testing no es opcional: es esencial. En proyectos colaborativos y escalables, contar con pruebas automatizadas bien estructuradas marca la diferencia entre un código confiable y uno frágil. Deno 2 ofrece herramientas nativas poderosas para testear, pero muchas veces su uso avanzado no está del todo documentado. Este artículo muestra cómo implementar un enfoque de testing avanzado en Deno 2, incluyendo mocks manuales, cobertura de código y organización por capas.
¿Por qué testear en Deno 2? Link to heading
Deno 2 cuenta con un sistema de testing nativo muy sólido:
- Sintaxis clara para definir y ejecutar tests.
- Aislamiento automático de cada test.
- Herramientas para cobertura de código (
deno coverage
). - Posibilidad de testear sin librerías externas.
Esto permite aplicar testing por capas y simular distintos escenarios sin introducir dependencias innecesarias.
Tipos de pruebas por capa Link to heading
✅ Pruebas unitarias Link to heading
Se enfocan en una función o clase específica, con dependencias simuladas.
🔄 Pruebas de integración Link to heading
Verifican cómo interactúan varios componentes entre sí, sin tocar la capa HTTP.
🌐 Pruebas end-to-end (E2E) Link to heading
Simulan una petición real, verificando el comportamiento de la aplicación de punta a punta.
Organización recomendada de carpetas Link to heading
tests/
├── unit/
│ └── get_all_tasks_test.ts
├── integration/
│ └── task_repository_test.ts
└── e2e/
└── api_tasks_test.ts
Esto permite escalar los tests de forma ordenada y mantener una separación lógica.
Mocks en Deno 2 sin librerías externas Link to heading
Deno permite crear mocks fácilmente utilizando clases o funciones anónimas. Ejemplo:
// Mock de TaskRepository
class MockTaskRepo {
private tasks = [{ id: "1", title: "Test", completed: false }];
findAll() {
return Promise.resolve(this.tasks);
}
}
Uso en el test:
import { assertEquals } from "https://deno.land/std@0.224.0/assert/mod.ts";
import { GetAllTasks } from "@app/use_cases/get_all_tasks.ts";
Deno.test("Devuelve tareas del repositorio mockeado", async () => {
const repo = new MockTaskRepo();
const useCase = new GetAllTasks(repo);
const result = await useCase.execute();
assertEquals(result.length, 1);
});
Simulación de errores Link to heading
También podés simular excepciones:
class FailingRepo {
findAll() {
throw new Error("DB unavailable");
}
}
Deno.test("Manejo de error en repositorio", () => {
const useCase = new GetAllTasks(new FailingRepo());
try {
useCase.execute();
} catch (e) {
assertEquals(e.message, "DB unavailable");
}
});
Cobertura de código en Deno 2 Link to heading
1. Ejecutar tests con cobertura: Link to heading
deno test --coverage=coverage/
2. Generar informe legible: Link to heading
deno coverage coverage/ --lcov > coverage.lcov
3. Ver informe HTML: Link to heading
genhtml coverage.lcov -o coverage_html
Podés usar genhtml desde lcov
(requiere instalación externa).
Automatización con GitHub Actions Link to heading
Un flujo simple para ejecutar los tests y verificar la cobertura:
name: test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: v2.x
- name: Run Tests
run: deno test --coverage=coverage/
También podés subir la cobertura a coveralls.io o codecov.io si querés seguimiento continuo.
Buenas prácticas Link to heading
- ✅ Nombrar tests descriptivamente.
- ✅ Mantener las dependencias mínimas.
- ✅ Testear cada capa por separado.
- ✅ Usar import maps para simplificar imports.
- ✅ Evitar testear implementaciones internas.
Conclusión Link to heading
Con Deno 2, tenés todo lo necesario para aplicar pruebas por capas, cobertura de código y mocks sin dependencias externas. Adoptar estas prácticas no solo mejora la calidad de tu software, sino que también facilita la colaboración en proyectos open source.