throwsexception - C#: ¿Cómo verifico "no se produjo ninguna excepción" en mi prueba unitaria?
unit test exception (5)
Estoy escribiendo una prueba unitaria para este método que devuelve "vacío". Me gustaría tener un caso en el que la prueba pase cuando no se arroje ninguna excepción. ¿Cómo escribo eso en C #?
Assert.IsTrue(????)
(Creo que así es como debería comprobarlo, pero ¿qué pasa con "???")
Espero que mi pregunta sea lo suficientemente clara.
En NUnit, puedes usar:
Assert.DoesNotThrow(<expression>);
para afirmar que su código no arroja una excepción. Aunque la prueba fallaría si se lanza una excepción, incluso si no hubiera un Assert a su alrededor, el valor de este enfoque es que luego puede distinguir entre las expectativas no satisfechas y los errores en sus pruebas, y tiene la opción de agregar un mensaje personalizado que se mostrará en su salida de prueba. Un resultado de prueba bien redactado puede ayudarlo a localizar errores en su código que hayan causado que falle una prueba.
Creo que es válido agregar pruebas para garantizar que su código no arroje excepciones; por ejemplo, imagina que estás validando la entrada y necesitas convertir una cadena entrante a una larga. Puede haber ocasiones en que la cadena sea nula, y esto es aceptable, por lo que debe asegurarse de que la conversión de cadena no arroje una excepción. Por lo tanto, habrá un código para manejar esta ocasión, y si no ha escrito una prueba, perderá cobertura en torno a una parte importante de la lógica.
Esta clase de ayuda me rascó la comezón con MSTest. Tal vez también puede rasguñar el tuyo.
[TestMethod]
public void ScheduleItsIneligibilityJob_HasValid_CronSchedule()
{
// Arrange
var factory = new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
// Assert
AssertEx.NoExceptionThrown<FormatException>(() =>
// Act
_service.ScheduleJob(scheduler)
);
}
public sealed class AssertEx
{
public static void NoExceptionThrown<T>(Action a) where T:Exception
{
try
{
a();
}
catch (T)
{
Assert.Fail("Expected no {0} to be thrown", typeof(T).Name);
}
}
}
La prueba de su unidad fallará de todos modos si se lanza una excepción: no necesita ingresar una afirmación especial.
Este es uno de los pocos escenarios en los que verá pruebas unitarias sin aserciones en absoluto: la prueba fracasará implícitamente si se produce una excepción.
Sin embargo, si realmente desea escribir una afirmación para esto, tal vez para poder detectar la excepción e informar "no esperaba excepción, pero obtuvo esto ...", puede hacer esto:
[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
var myObject = new MyObject();
try
{
myObject.MethodUnderTest();
}
catch (Exception ex)
{
Assert.Fail("Expected no exception, but got: " + ex.Message);
}
}
(Lo anterior es un ejemplo para NUnit, pero lo mismo vale para MSTest)
Me gusta ver un Assert.Whatever
al final de cada prueba, solo por coherencia ... sin uno, ¿realmente puedo estar seguro de que no se supone que haya uno allí?
Para mí, esto es tan simple como poner Assert.IsTrue(true);
Sé que no puse accidentalmente ese código allí, y por lo tanto debería tener la suficiente confianza en un rápido vistazo que esto fue como se esperaba.
[TestMethod]
public void ProjectRejectsGappedVersioningByDefault() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => {
var sut = new ScriptProject(files);
});
}
[TestMethod]
public void ProjectAcceptsGappedVersionsExplicitly() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
var sut = new ScriptProject(files, true);
Assert.IsTrue(true); // Assert.Pass() would be nicer... build it in if you like
}
No pruebes que algo no sucede . Es como asegurar que el código no se rompa . Eso es un poco implícito, todos nos esforzamos por un código sin errores y sin fallas. ¿Quieres escribir pruebas para eso? ¿Por qué solo un método? ¿No quieres que se prueben todos tus métodos para que no arrojen alguna excepción ? Siguiendo ese camino, terminarás con una prueba extra, ficticia y sin afirmación para cada método en tu base de códigos. No trae valor.
Por supuesto, si su requisito es verificar que el método detecta excepciones , lo prueba (o lo revierte un poco, prueba que no arroja lo que se supone que atrapa).
Sin embargo, el enfoque / las prácticas generales permanecen intactos: no se escriben pruebas para algunos requisitos artificiales / imprecisos que están fuera del alcance del código probado (y la prueba de que "funciona" o "no arroja" suele ser un ejemplo de tal - especialmente en el escenario cuando las responsabilidades del método son bien conocidas).
Para simplificar: concéntrese en lo que su código tiene que hacer y pruebe eso.