Este es mi primer intento de hacer pruebas unitarias, así que tenga paciencia conmigo.
I'm still trying to unit test a library that converts lists of POCOs to ADO.Recordsets.¿Cómo puedo evitar múltiples afirmaciones en esta prueba unitaria?
En este momento, intento escribir una prueba que crea un List<Poco>
, la convierte en un Recordset (usando el método que quiero probar) y luego comprueba si contienen la misma información (como, Poco.Foo == RS.Foo
, y pronto...).
Esta es la POCO:
public class TestPoco
{
public string StringValue { get; set; }
public int Int32Value { get; set; }
public bool BoolValue { get; set; }
}
... y esta es la prueba hasta el momento (estoy usando xUnit.net):
[Fact]
public void TheTest()
{
var input = new List<TestPoco>();
input.Add(new TestPoco { BoolValue = true, Int32Value = 1, StringValue = "foo" });
var actual = input.ToRecordset();
Assert.Equal(actual.BoolValue, true);
Assert.Equal(actual.Int32Value, 1);
Assert.Equal(actual.StringValue, "foo");
}
Lo que no gusta de estos son los tres asertos al final, uno por propiedad del POCO.
He leído muchas veces que las afirmaciones múltiples en una prueba son malas (y entiendo los motivos, y estoy de acuerdo).
El problema es, ¿cómo puedo deshacerme de ellos?
tengo excelente libro de Roy "The Art of Unit Testing" Osherove justo en frente de mí, y él tiene un ejemplo que cubre exactamente este (para los que tienen el libro: el capítulo 7.2.6, página 202/203):
En su ejemplo, el método bajo prueba devuelve un objeto AnalyzedOutput
con varias propiedades, y quiere afirmar todas las propiedades para verificar si cada una contiene el valor esperado.
La solución en este caso:
crear otro AnalyzedOutput
ejemplo, llenarla con los valores esperados y afirmar si es igual a la devuelta por el método bajo prueba (y anulan Equals()
para ser capaz de hacer esto).
Pero creo que no puedo hacer esto en mi caso, porque el método que deseo probar arroja un ADODB.Recordset
.
Y con el fin de crear otro Recordset
con los valores esperados, yo primero tendrá que crearlo desde cero:
// this probably doesn't actually compile, the actual conversion method
// doesn't exist yet and this is just to show the idea
var expected = new ADODB.RecordsetClass();
expected.Fields.Append("BoolValue", ADODB.DataTypeEnum.adBoolean);
expected.Fields.Append("Int32Value", ADODB.DataTypeEnum.adInteger);
expected.Fields.Append("StringValue", ADODB.DataTypeEnum.adVarWChar);
expected.AddNew();
expected.BoolValue = true;
expected.Int32Value = 1;
expected.StringValue = "foo";
expected.Update();
No me gusta este tampoco, porque esto es básicamente una duplicación de algunas del código en el método de conversión real (el método bajo prueba), que es otra cosa para evitar en las pruebas.
Entonces ... ¿qué puedo hacer ahora?
¿Este nivel de duplicación sigue siendo aceptable en esta situación especial o existe una forma mejor de probarlo?
es por eso que es el "arte" de las pruebas unitarias y no la "ciencia" ... – Berryl
Múltiples afirmaciones en un caso de prueba no son malas. La idea de que cada caso de prueba debe tener solo una afirmación [es tonto] (http://stackoverflow.com/a/20300843/545127). – Raedwald