Aquí podría ser tu PUBLICIDAD


Después de golpear la prueba expectedexception termina

votos
4

Estoy probando el método de eliminación de una clase abstracta de repositorio base que es heredada por varias otras clases de repositorio. MyTestRepository hereda la base, por lo que puedo ejecutar pruebas contra los métodos de la base sin restringir mi prueba al uso de una clase concreta. Cuando ejecuto mi prueba unitaria pasa, pero luego noté que tengo varios objetos OrderDetail y Schedule en el DB de prueba generados por la prueba (los objetos se crean durante la inicialización de la prueba) y no se eliminan, mientras que el objeto Order se elimina. Agregué algunos puntos de interrupción y noté que tan pronto como el método de ayuda finaliza y se lanza la excepción esperada, la prueba finaliza y las otras llamadas al ayudante nunca ocurren.

Este es mi primer intento de pruebas unitarias. ¿Mis metodologías están equivocadas? ¿ExpectedException funciona según lo previsto y la estoy utilizando de forma incorrecta o hay otra herramienta que debería utilizar? La única forma en que puedo pensar para obtener mi prueba es poner un bloque try catch en el helper y afirmar la verdad cuando atrapo mi DataAccessException.

    [TestMethod]
    [ExpectedException(typeof(DataAccessException))]
    public void NHibernateRepositoryBaseDelete()
    {
        NHibernateRepositoryBaseDeleteHelper<Order, int>(myOrder, myOrder.OrderId);
        NHibernateRepositoryBaseDeleteHelper<OrderDetail, int>(myOrderDetail, myOrderDetail.OrderDetailId);
        NHibernateRepositoryBaseDeleteHelper<Schedule, int>(mySchedule, mySchedule.ScheduleId);
    }

    private static void NHibernateRepositoryBaseDeleteHelper<T, TKey>(T myItem, TKey myItemId)
    {
        MyTestRepository<T, TKey> myRepository = new MyTestRepository<T, TKey>();
        myRepository.Delete(myItem);
        myRepository.CommitChanges();

        myRepository.GetById(myItemId, false);
    }
Publicado el 12/03/2009 a las 21:19
fuente por usuario Justin Holbrook
En otros idiomas...        العربية       

2 respuestas

votos
10

En general, no uso a ExpectedExceptionmenos que pueda hacer que la excepción se arroje en una sola declaración, o si otras pruebas aseguran que las declaraciones anteriores no arrojen la excepción.

Aquí, básicamente tiene tres pruebas: está probando que cada una de esas llamadas eliminará una excepción. Todo lo que ExpectedExceptionhace es ejecutar el método y verificar que arrojó la excepción que solicitó: no intenta continuar desde donde se lanzó la excepción, esperando que se lance de nuevo.

Si desea verificar que una pieza específica de código arroje una excepción (en lugar de solo el método completo), use:

try
{
    OperationThatShouldFail();
    Assert.Fail("Expected exception");
}
catch (DataAccessException)
{
    // Expected (no need for an assertion though)
}

(Y no tiene ExpectedExceptionmás: ya no espera que arroje el método de prueba).

Tendría uno de estos bloques para cada uno de los tres controles. Alternativamente (y probablemente mejor) solo tiene tres pruebas, cada una de las cuales usa ExpectedExceptionpero solo tiene una línea de longitud. Como otra alternativa, podrías ponerlo try/catchen tu método de ayuda.

También es posible que desee tener una afirmación al final de la prueba de que las tablas relevantes están vacías, pero eso depende de su situación.

EDITAR: En cuanto a cuando limpia la base de datos: generalmente me gusta limpiarlo al comienzo de cada prueba, de modo que si ejecuto solo una prueba de falla, puedo ver el estado de la base de datos posteriormente. Si tuviera que limpiarlo en el método de desmontaje, habría perdido información valiosa (o me verían obligado a permanecer en el depurador).

EDITAR: Otra alternativa a ExpectedException(que sospecho que ahora está en muchos marcos de prueba) es tener un método genérico como este:

static void ExpectException<T>(Action action) 
    where T : Exception
{
    try
    {
        action();
        Assert.Fail("Expected exception " + typeof(T));
    }
    catch (T)
    {
        // Expected
    }
}

A continuación, puede llamarlo fácilmente (varias veces) desde el método utilizando una expresión lambda para la acción, suponiendo que está utilizando C # 3. Por ejemplo:

// Method name shortened for simplicity, and I'm assuming that type inference
// will work too.
public void NHibernateRepositoryBaseDelete()
{
    ExpectException<DataAccessException>(() => 
        DeleteHelper(myOrder, myOrder.OrderId));
    ExpectException<DataAccessException>(() => 
       DeleteHelper(myOrderDetail, myOrderDetail.OrderDetailId));
    ExpectException<DataAccessException>(() => 
       DeleteHelper(mySchedule, mySchedule.ScheduleId));
}
Respondida el 12/03/2009 a las 09:28
fuente por usuario Jon Skeet


Aquí podría ser tu PUBLICIDAD


votos
5

Envuelva su código de prueba unitaria en un bloque try / finally y limpie su base de datos dentro de la parte finally.

[TestMethod]    
[ExpectedException(typeof(DataAccessException))]    
public void NHibernateRepositoryBaseDelete()    
{
    try
    {
        NHibernateRepositoryBaseDeleteHelper<Order, int>(myOrder, myOrder.OrderId);
        NHibernateRepositoryBaseDeleteHelper<OrderDetail, int>(myOrderDetail, myOrderDetail.OrderDetailId);
        NHibernateRepositoryBaseDeleteHelper<Schedule, int>(mySchedule, mySchedule.ScheduleId);
    }
    finally
    {
        // clean up database here
    }   
}
Respondida el 12/03/2009 a las 09:29
fuente por usuario Robert Lewis