¿Cómo simular eventos que causan excepciones para probar bloques try / catch?

14

Entiendo cómo funcionan las excepciones y cómo detectarlas y manejarlas en C #, pero ¿cómo puedo simular eventos que puedan causar una excepción para garantizar que se capturen correctamente? Por ejemplo, ¿es posible ejecutar una aplicación en una especie de banco de pruebas donde es posible simular problemas de red, problemas de bases de datos, etc.? Las excepciones por su naturaleza parecen difíciles de reproducir, por lo que es difícil garantizar que su código pueda hacer frente a ellas.

Aunque principalmente desarrollo usando C # /. NET / Visual Studio, las respuestas o recursos relacionados con otros lenguajes podrían ser útiles.

Muelles Myers
fuente
Otra posible solución se describe en este artículo de MSDN: Prueba de inyección de falla con TestApi
Giorgi

Respuestas:

13

1) Si siguió el modelo de inyección de dependencia, podría sustituir implementaciones reales de ciertas partes con las simulaciones que arrojarían excepciones a medida que las necesite. Sin embargo, eso requeriría que usted diseñara inicialmente su aplicación de una manera específica o que la rediseñara por completo.

Me gusta:

public class SqlUsersRepository : IUsersRepository
{
    public void RegisterNewUser (User newUser)
    {
        throw new SqlException ("Connection timeout");
    }
}

Sin embargo, aquí tendríamos el problema de que el código del consumidor no debería ocuparse de manejar excepciones de implementación concretas.

2) Otro enfoque es reemplazar ciertas llamadas a métodos con sus envoltorios personalizados.

En lugar de:

FileStream fs = File.OpenRead (path);

tu usas:

FileStream fs = File.OpenRead_Test (path);

proporcionando un método de extensión personalizado (solo una idea rápida):

public static FileStream OpenRead_Test (this System.IO.File file, string path)
{
    throw new FileNotFoundException ();
}

fuente
3

Debes mirar los marcos burlones.

Con estos, utiliza la inyección de dependencia para llamar a la base de datos falsa (digamos) en lugar de la real. Esto significa que tiene control total sobre lo que se devuelve para cada llamada.

Luego configura una prueba que cuando se llama simplemente arroja la excepción deseada:

public void Test1()
{
    throw new NullArgumentException();
}

Su prueba pasa cuando su código maneja esto correctamente.

ChrisF
fuente
3

La burla y la inyección solo pueden llegar hasta cierto punto y requieren grandes cambios de enfoque en algunos casos.

Si no desea rediseñar su aplicación para que se ajuste a un marco de prueba, entonces lo que realmente necesita es un host o entorno preparado para errores. Hay muchas maneras de simular la lentitud de nuestra interrupción de la red (incluso las herramientas de prueba de Microsoft tienen un poco de esto en el área de prueba web). He tenido el mayor éxito al colocar máquinas detrás de un enrutador que puede manipularse para cambiar las simulaciones en coordinación con un conjunto de bases de datos para producir errores y scripts para cambiar los errores que produce la base de datos.

Incluso con eso, si vas lo suficientemente rápido o lo suficientemente lejos hacia el hardware, hay errores como problemas de concurrencia y fallas de escritura demoradas que prácticamente no puedes simular. A veces tienes que causarlos de verdad y otras veces solo tienes que trabajar sin la red de seguridad.

Cuenta
fuente
De acuerdo: en algunos casos, no puede permitirse los gastos generales de la inyección de dependencia en su código de lanzamiento, por ejemplo. No es un problema cotidiano, pero puede suceder.
Steve314