Cuando la propiedad se define en la base de datos de producción (o un clon para pruebas), esto no es una prueba unitaria . Una prueba unitaria verifica una unidad de trabajo y no requiere un estado externo particular para funcionar. Esto supone que Offer1
se define en la base de datos como una oferta solo para hombres. Eso es un estado externo. Esto es más una prueba de integración , específicamente un sistema o una prueba de 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 se realizan manualmente por seres humanos).
Cuando la propiedad se define en el modelo de dominio con una if
declaración, la misma prueba es una prueba unitaria. 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 empresarial es configurable en lugar de codificado. Debido a que una implementación apresurada 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).
Puede estar utilizando un marco de prueba de unidad para ejecutar la prueba. Pero los marcos de pruebas unitarias no se limitan a ejecutar pruebas unitarias. También pueden ejecutar pruebas de integración.
Si estuviera escribiendo una prueba unitaria, crearía ambas person
y 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 en función de la lógica empresarial. No es afirmativo lo que offer1
rechaza a las mujeres. Está haciendo offer1
el tipo de oferta que rechaza a las mujeres.
Puede crear y configurar la base de datos como parte de la prueba. En C #, usando NUnit, o en JUnit de Java, configuraría la base de datos en un Setup
método. Presumiblemente su marco de prueba tiene una noción similar. En ese método, puede insertar registros en la base de datos con SQL.
Si le resulta difícil escribir código que sustituya una base de datos de prueba por la base de datos de producción, eso 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 dueño del negocio (no necesariamente el dueño corporativo, más como la persona responsable de este producto en la jerarquía corporativa) configurar las reglas comerciales directamente. Porque si tiene este tipo de marco técnico, es fácil permitir que el propietario de la empresa use una interfaz de usuario (UI) para configurar la oferta. El propietario de la empresa seleccionaría la limitación en la interfaz de usuario y emitiría la markLimitedToGender("M")
llamada. Luego, cuando la oferta persiste en la base de datos, la almacena. Pero no necesitaría 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 dueño 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 pruebas (o pruebas y luego código). Ese 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.