Yeda AI Tips · #070

English

No confíes en los tests con base de datos en memoria

Tus tests con base de datos en memoria te están mintiendo. Un fake en memoria nunca traduce tus consultas al dialecto SQL que habla tu base de datos de producción: las evalúa como operaciones en proceso. Por eso una consulta puede pasar todos los tests en tu máquina y aun así fallar, o devolver filas distintas en silencio, la primera vez que toca el motor real.

Read this article in English

Por qué los tests en verde se rompen en producción

Una consulta de ORM son en realidad dos programas: la consulta que escribiste y el SQL al que el proveedor la traduce. Un fake en memoria ejecuta solo el primero. Todo lo que vive en la capa de traducción queda sin probar:

La propia documentación de EF Core de Microsoft es directa: usar el proveedor en memoria como fake de pruebas está "altamente desaconsejado" y se mantiene solo para aplicaciones legadas.

La solución: probar las consultas riesgosas contra un motor real

"Los tests con base de datos real son lentos y dolorosos" era cierto en 2015. Hoy el costo de configuración es un contenedor:

// Testcontainers: a real PostgreSQL, per test run, auto-cleaned
var pg = new PostgreSqlBuilder().Build();
await pg.StartAsync();
var options = new DbContextOptionsBuilder<AppDbContext>()
    .UseNpgsql(pg.GetConnectionString())
    .Options;

Testcontainers (disponible para .NET, Java, Go, Node, Python y más) levanta en Docker el mismo motor que corres en producción, entrega a tus tests una cadena de conexión y lo limpia al terminar. La suite del propio equipo de EF Core ejecuta más de 30,000 tests contra SQL Server real en unos minutos, en cada commit: una base de datos local con un dataset razonable es rápida, porque todo queda en una sola máquina.

El verdadero trabajo de diseño es el aislamiento, no la velocidad. La receta estándar: crear y sembrar la base de datos una vez por corrida (un fixture compartido), envolver cada test que modifica datos en una transacción que nunca se confirma, y dar a los tests que sí deben confirmar su propia base de datos más un paso de limpieza.

Reglas prácticas

SituaciónProbar contra
Lógica de negocio pura, sin consultasSin base de datos: stub de la capa de datos
Consultas LINQ/ORM, joins, filtrosMotor real (en contenedor)
SQL crudo en cualquier puntoMotor real: los fakes no pueden ejecutarlo
Transacciones, comportamiento de rollbackMotor real: en memoria se ignoran
Migraciones antes de un releaseMotor real, versión de producción
De verdad necesitas un fake rápidoSQLite en memoria antes que el proveedor en memoria del ORM — y su dialecto también difiere

Notas para usuarios avanzados

Conserva la memoria (o mejor, repositorios con stubs) para la velocidad en lógica pura — pero demuestra cada consulta riesgosa, migración y transacción contra el motor real antes de que llegue a producción.

Recursos

¿Construyendo una funcionalidad con AI? Yeda AI diseña, audita y entrega sistemas LLM de producción.

Habla con nosotros · Lee el blog