2011-09-26 21 views
8

Czy istnieje bardziej elegancki sposób na wykonanie wyjątku throws w Androidzie, niż to?Jak przetestować wyjątek wyrzuca w Androidzie

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

     } 
} 

Coś takiego nie działa ?!

@Test(expected=ElementNotFoundException .class) 

Dzięki, Mark

Odpowiedz

5

Używasz zawodnik testowy junit4? Adnotacja @Test nie zadziała, jeśli prowadzisz testowego junit3. Sprawdź wersję, której używasz.

Po drugie, zalecanym sposobem sprawdzenia wyjątków w kodzie jest użycie reguły (wprowadzonej w junicie 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); 
} 

Można nadal używać @Test (oczekiwane = IOException.class), ale powyżej ma tę zaletę, że jeśli jest wyjątek, zanim exception.expect nazywa, test zakończy się niepowodzeniem.

+1

Android korzysta z wersji 3.x JUnit więc wydaje się, że nie ma innego sposobu - z wyjątkiem m.in. junit4 i przełączyć się na ten z Androidem JUnit. – Mark

+0

Po prostu uruchomiłem to z junitem: 4.12 i wymyśliłem, że exception.expectMessage ("Ikona jest pusta, nie jest plikiem lub nie istnieje."); nie zawiedzie testu, jeśli oczekiwany komunikat nie pasuje. – takesavy

2

Tak to robię. Tworzę statyczną metodę o nazwie assertThrowsException, która przyjmuje jako argumenty oczekiwaną klasę wyjątków i Runnable, która zawiera testowany kod.

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."); 
      } 
     } 
    } 
} 

To jest przykładowy kod używać specjalnego dochodzić w swojej klasie testu (który rozciąga AndroidTestCase lub jedną z jej pochodnych):

public void testShouldThrowInvalidParameterException() { 

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

} 

Tak, jest dużo pracy, ale lepiej niż przenoszenie junit4 na Androida.

+0

Nie jestem pewien, czy 'assertThrowsException' ma słuszność. 'Throwable' z pierwszego' Assert.fail' zostanie przechwycony iw pewnym przypadku nie jest instancją zamierzonej klasy wyjątków, pojawi się następny 'Assert.fail'. – SK9

3

Zrobiłem coś bardzo podobnego do hopia's answer z kilkoma ulepszeniami. Zwróciłem obiekt wyjątku, aby można było sprawdzić jego komunikat lub inne właściwości, i zadeklarowałem interfejs , który zastąpi Runnable, ponieważ Runnable nie pozwala na testowanie kodu podczas sprawdzania wyjątków.

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; 
} 

Oto przykład nazywania go.

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

Przy pomocy junit3 może pomóc poniższe wskazówki.

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."); 
    } 
} 
Powiązane problemy