2011-09-26 22 views
8

¿Existe una forma más elegante de hacer una excepción throw throws en Android luego de esto?Cómo probar la excepción de throw throws en Android

public void testGetNonExistingKey() { 
     try { 
      alarm.getValue("NotExistingValue"); 
      fail(); 
     } catch (ElementNotFoundException e) { 

     } 
} 

¿Algo como esto no funciona ?!

@Test(expected=ElementNotFoundException .class) 

Gracias, Mark

Respuesta

5

¿Está utilizando un corredor de prueba junit4? La anotación @Test no funcionará si está ejecutando un corredor de prueba junit3. Verifica la versión que estás usando.

En segundo lugar, la forma recomendada de verificar excepciones en su código es usar una Regla (presentada en el punto 4.7).

@Rule 
public ExpectedException exception = ExpectedException.none(); 

@Test 
public void throwsIllegalArgumentExceptionIfIconIsNull() { 
    // do something 

    exception.expect(IllegalArgumentException.class); 
    exception.expectMessage("Icon is null, not a file, or doesn't exist."); 
    new DigitalAssetManager(null, null); 
} 

Puede seguir utilizando el @test (esperado = IOException.class), pero lo anterior tiene la ventaja de que si se produce una excepción antes de que el exception.expect se llama, entonces la prueba fallará.

+1

Android está usando una versión 3.x de junit, así que parece que no hay otra manera, excepto para incluir junit4 y cambiar a esto desde el junit de Android. – Mark

+0

Acabo de ejecutar esto con el junit: 4.12 y me figuré que exception.expectMessage ("El icono es nulo, no es un archivo, o no existe."); no falla la prueba si el mensaje esperado no coincide. – takesavy

2

Así es como lo hago. Creo un método estático llamado assertThrowsException que toma como argumentos una clase de excepción esperada y Runnable que contiene el código bajo prueba.

import junit.framework.Assert; 

public SpecialAsserts { 
    public void assertThrowsException(final Class<? extends Exception> expected, final Runnable codeUnderTest) { 
     try { 
      codeUnderTest.run(); 
      Assert.fail("Expecting exception but none was thrown."); 
     } catch(final Throwable result) { 
      if (!expected.isInstance(result)) { 
       Assert.fail("Exception was thrown was unexpected."); 
      } 
     } 
    } 
} 

Este es el código de ejemplo para utilizar la aserción especial en su clase de prueba (que se extiende AndroidTestCase o uno de sus derivados):

public void testShouldThrowInvalidParameterException() { 

    SpecialAsserts.assertThrowsException(InvalidParameterException.class, new Runnable() { 
     public void run() { 
      callFuncThatShouldThrow(); 
     } 
    }); 

} 

Sí, hay un montón de trabajo, pero es mejor que portar junit4 a android.

+0

No estoy seguro de que 'assertThrowsException' sea correcto. El 'Throwable' del primer' Assert.fail' será capturado y en el caso de que no sea una instancia de la clase de excepción prevista, el siguiente 'Assert.fail' se activará. – SK9

3

Hice algo muy similar a hopia's answer con un par de mejoras. Hice que devuelva el objeto de excepción para que pueda verificar su mensaje o cualquier otra propiedad, y he declarado una interfaz Testable para reemplazar Runnable porque Runnable no permite que el código de prueba arroje excepciones.

public interface Testable { 
    public void run() throws Exception; 
} 

public <T extends Exception> T assertThrows(
     final Class<T> expected, 
     final Testable codeUnderTest) throws Exception { 
    T result = null; 
    try { 
     codeUnderTest.run(); 
     fail("Expecting exception but none was thrown."); 
    } catch(final Exception actual) { 
     if (expected.isInstance(actual)) { 
      result = expected.cast(actual); 
     } 
     else { 
      throw actual; 
     } 
    } 
    return result; 
} 

Aquí hay un ejemplo de cómo llamarlo.

InvalidWordException ex = assertThrows(
    InvalidWordException.class, 
    new Testable() { 
     @Override 
     public void run() throws Exception { 
      model.makeWord("FORG", player2); 
     } 
    }); 

assertEquals(
     "message", 
     "FORG is not in the dictionary.", 
     ex.getMessage()); 
0

Con junit3 lo siguiente puede ayudar.

public static void assertThrows(Class<? extends Throwable> expected, 
     Runnable runnable) { 
    try { 
     runnable.run(); 
    } catch (Throwable t) { 
     if (!expected.isInstance(t)) { 
      Assert.fail("Unexpected Throwable thrown."); 
     } 
     return; 
    } 
    Assert.fail("Expecting thrown Throwable but none thrown."); 
} 

public static void assertNoThrow(Runnable runnable) { 
    try { 
     runnable.run(); 
    } catch (Throwable t) { 
     Assert.fail("Throwable was unexpectedly thrown."); 
    } 
} 
Cuestiones relacionadas