Cuando la propiedad está definida en la base de datos de producción (o un clon para la prueba), esto no es una prueba de unidad . Una prueba de unidad verifica una unidad de trabajo y no requiere un estado externo particular para funcionar. Esto supone que Offer1
está definido en la base de datos como una oferta solo para hombres. Ese es el estado externo. Así que esto es más una prueba de integración , específicamente una system o aceptación . Tenga en cuenta que las pruebas de aceptación a menudo no están programadas (no se ejecutan en un marco de prueba, sino que son realizadas manualmente por seres humanos).
Cuando la propiedad se define en el modelo de dominio con una declaración if
, la misma prueba es una prueba de unidad. Y puede ser frágil. Pero el verdadero problema es que el código es frágil. Como regla general, su código será más resistente si el comportamiento del negocio es configurable en lugar de codificado. Debido a que una implementación rápida para corregir un pequeño error de codificación debería ser rara. Pero un requisito comercial que cambia sin previo aviso es solo un martes (algo que sucede semanalmente).
Es posible que esté utilizando un marco de prueba de unidad para ejecutar la prueba. Pero los marcos de pruebas unitarias no se limitan a ejecutar pruebas unitarias. Pueden y también ejecutan pruebas de integración.
Si estuvieras escribiendo una prueba de unidad, crearías tanto person
como offer1
desde cero sin depender del estado de la base de datos. Algo como
[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
var personId = Guid.NewGuid();
var gender = "F";
var person = new Person(personId, gender);
var id = Guid.NewGuid();
var offer1 = new Offer1(id, "ReturnsFalseWhenGivenAPersonWithAGenderOfFemale");
offer1.markLimitedToGender("M");
Assert.False(offer1.IsEligible(person));
}
Tenga en cuenta que esto no cambia según la lógica empresarial. No está afirmando que offer1
rechaza a las mujeres. Está haciendo que offer1
sea el tipo de oferta que rechaza a las mujeres.
Puede crear y configurar la base de datos como parte de la prueba. En C #, utilizando NUnit, o en JUnit de Java, configuraría la base de datos en un método Setup
. Presumiblemente, su marco de prueba tiene una noción similar. En ese método, podría insertar registros en la base de datos con SQL.
Si es difícil para usted escribir código que sustituya una base de datos de prueba por la base de datos de producción, suena como una debilidad de prueba en su aplicación. Para las pruebas, sería mejor usar algo como inyección de dependencia que permita la sustitución. Luego, podría escribir pruebas que sean independientes de las reglas comerciales actuales.
Un beneficio adicional de esto es que a menudo es más fácil para el propietario de la empresa (no necesariamente el propietario de la empresa, más como la persona responsable de este producto en la jerarquía corporativa) configurar las reglas de negocios directamente. Porque si tiene este tipo de marco técnico, es fácil permitir que el propietario de la empresa utilice una interfaz de usuario (UI) para configurar la oferta. El propietario del negocio seleccionaría la limitación en la interfaz de usuario y emitiría la llamada markLimitedToGender("M")
. Luego, cuando la oferta se mantiene en la base de datos, almacenaría esto. Pero no necesitarías almacenar la oferta para usarla. Por lo tanto, sus pruebas podrían crear y configurar una oferta que no existe en la base de datos.
En su sistema, como se describe, el propietario del negocio tendría que presentar una solicitud al grupo técnico, que emitiría el SQL apropiado y actualizaría las pruebas. O el grupo técnico tiene que editar su código y sus pruebas (o las pruebas luego codificar). Eso parece un enfoque bastante pesado. Puedes hacerlo. Pero su software (no solo sus pruebas) sería menos frágil si no tuviera que hacerlo.
TL; DR : puede escribir pruebas como esta, pero es mejor que escriba su software para no tener que hacerlo.