Cuando hacemos Snapshot Testing, el mayor enemigo es el determinismo. Si tu objeto tiene fechas, IDs autogenerados o tokens de sesión, el test fallará siempre porque esos valores cambian en cada ejecución. El Scrubbing es el proceso de interceptar esos valores y reemplazarlos por placeholders estáticos antes de guardar la «foto».
El Concepto: Antes y Después del Scrubbing
Imagina este objeto que representa una transacción de nuestra API:
Snapshot Recibido (Sin Scrubbing) – TEST FALLA CADA SEGUNDO
{
"OrderId": "7b8e1a-45...",
"ProcessedAt": "2026-02-14T12:00:01.456Z",
"ServerName": "NODE-PROD-01"
}
Snapshot Verificado (Con Scrubbing) – TEST ESTABLE
{
"OrderId": "Guid_1",
"ProcessedAt": "2026-02-14",
"ServerName": "{Scrubbed}"
}
Tipos de Scrubbing (Tutorial Paso a Paso)
Verify ofrece tres niveles de limpieza dependiendo de qué tan profundo necesites llegar en el árbol de objetos.
A. Scrubbing Global (Recomendado para Guids y Fechas)
En lugar de hacerlo test por test, configuras Verify una vez para que siempre limpie ciertos patrones.
[ModuleInitializer]
public static void Initialize()
{
// Reemplaza todos los GUIDs aleatorios por Guid_1, Guid_2, etc.
VerifierSettings.ScrubGuids();
// Normaliza las fechas para que no fallen por milisegundos
VerifierSettings.ScrubDateTimes("yyyy-MM-dd");
}
B. Scrubbing de Miembros Específicos
Si quieres ocultar un campo sensible o uno que cambia por configuración de entorno:
[Fact]
public Task GetOrder_Scrubbed()
{
var result = service.GetOrder();
return Verify(result)
.ScrubMember<Order>(o => o.ServerName)
.ScrubMember("InternalTraceId"); // Por nombre de propiedad (string)
}
C. Scrubbing por Expresión Regular (RegEx)
Ideal para logs o strings complejos donde solo una parte es dinámica.
return Verify(logOutput)
.ScrubLinesWithReplace(line =>
Regex.Replace(line, @"Version=\d+\.\d+\.\d+", "Version=1.0.0"));
¿Cómo funciona el algoritmo de reemplazo?
Verify no solo borra el dato; lo mapea. Si en tu JSON aparece el mismo GUID tres veces, el motor de Scrubbing lo detectará y pondrá Guid_1 en todas esas apariciones para mantener la integridad referencial dentro del snapshot.
Estrategia de Contrapunto: Scrubbing vs. Datos Mockeados
| Estrategia | Ventaja | Desventaja |
| Mocking Fijo | El dato real nunca cambia (ej. usar fixedDateTime). | Requiere inyectar abstracciones de tiempo en todo el código. |
| Scrubbing | No tocas el código de producción. El código sigue usando DateTime.Now. | El snapshot pierde el «valor real» del dato (solo ves un placeholder). |
Notas
- Prioriza ScrubGuids(): Es la causa #1 de fallos en Snapshot Testing. Actívalo globalmente en tu ensamblado de tests.
- Usa ScrubLines para Logs: Si estás testeando la salida de consola o logs de Serilog, limpia los timestamps de cada línea para evitar ruido.
- Cuidado con el Orden: Verify aplica los scrubbers en el orden en que los llamas. Primero limpia los tipos complejos y luego los strings generales.
- Verifica el placeholder: Asegúrate de que el nombre del placeholder (ej. {Scrubbed}) sea lo suficientemente descriptivo para quien revise el Pull Request.
Conclusión
El scrubbing es lo que vuelve usable el snapshot testing en sistemas reales: transforma datos no deterministas (GUIDs, fechas, tokens, valores de entorno) en snapshots estables sin tocar código productivo. La clave es aplicarlo con estrategia: configura scrubbers globales para GUIDs y DateTimes, usa scrubbing de miembros para campos sensibles o dependientes del ambiente, y recurre a RegEx cuando el dinamismo vive dentro de strings o logs. Respeta el orden de los scrubbers para evitar reemplazos “demasiado agresivos” y valida que los placeholders sean claros para quien revise el PR. Bien hecho, el scrubbing reduce ruido, mantiene integridad referencial y convierte los diffs en señales útiles, no en falsas alarmas.
