2017-03-23 2 views
3

Dies ist der Code meines Dienstes:Mocking Ausnahmen mit Mockito: Unerwarteter Ausnahmefehler

public class Service { 
    public Object serviceMethod() throws MyException { 
     @Autowired 
     Dao dao; 

     try { 
     return dao.dao_method(); 
     } catch (ExceptionFromDaoMethod e) { 
     throw (new MyException()); 
     } 
    } 
} 

ich einen einfachen Unit-Test schreiben will; dies ist mein Testfall:

@Mock 
Dao dao; 

@InjectMocks 
Service service; 

@Test(expected=MyException.class) 
public void shouldReturnMyException throws MyException { 
    when(service.serviceMethod()).thenThrow(new MyException()); 
} 

Dieser Test schlägt fehl, weil ich eine unerwartete Ausnahme haben:

die erwartete Ausnahme ist MyException aber war org.mockito.exception.base.MockitoException

Warum? Was ist die Lösung?

aktualisiert Dank @Maciej Kowalski habe ich festgestellt, dass ich den wenn Zustand im Vergleich zu einer realen Klasse und nicht im Vergleich zu einem einem verspottet verwendet wurde. Also habe ich die Annotation @Spy zum Service im Unit Test hinzugefügt.
Der Code des neuen Tests ist:

@Mock 
Dao dao; 

@InjectMocks 
@Spy 
Service service; 

@Before 
MockitoAnnotations.initMocks(this); 

@Test(expected=MyException.class) 
public void shouldReturnMyException throws MyException { 
    doThrow(new MyException()).when(service.serviceMethod()); 
} 

Aber jetzt habe ich dieses Problem:

die erwartete Ausnahme ist MyException aber war

Antwort

1

Sie würden das müssen @spy Service, da ich annahm, dass Sie es als die Instanz verwenden, bei der echte Implementierung aufgerufen wird.

diese So versuchen:

@InjectMocks 
@Spy 
Service service; 

@Test(expected=MyException.class) 
public void shouldReturnMyException throws MyException { 
    doThrow(new MyException()).when(service).serviceMethod(); 
} 

mit Doxx beginnen erinnern, wenn ein @Spy spöttisch.

aktualisieren

Wenn Sie das dao Aufruf verspotten wollen (was eine bessere Testkandidat ist ..) Sie einige Änderungen vornehmen müssten, wenn Sie nur normales Mockito verwenden möchten.

Wenn die dao nicht die Instanz Abhängigkeit ist, dann werden Sie Ihre prod Methode ändern müssen:

public class Service { 
    public Object serviceMethod() throws MyException { 
     Dao dao = getDaoInstance(); 
     try { 
     return dao.dao_method(); 
     } catch (ExceptionFromDaoMethod e) { 
     throw (new MyException()); 
     } 
    } 

    Dao getDaoInstance(){ 
     return new Dao(); 
    } 
} 

Und Ihre Testklasse sollte mich mehr oder weniger wie folgt aus: Ich

@Mock 
Dao dao; 

@Spy 
Service service; 

@Test(expected=MyException.class) 
public void shouldReturnMyException throws MyException { 
    doReturn(dao).when(service).getDaoInstance(); 

    when(dao.dao_method()).thenThrow(new ExceptionFromDaoMethod()); 

    service.serviceMethod(); 
} 
+0

Können Sie mich erklären, warum meine Lösung ist falsch? Außerdem ist es in Ihrer Lösung wann (service.serviceMethod()) oder wann (service) .serviceMethod()? – PenguinEngineer

+0

Nun wird die unerwartete Ausnahme MyException erwartet, war aber PenguinEngineer

+0

Sie haben versucht, eine Instanz zu verspotten, die kein Mock ist, oder als Spion, so dass dies keine Auswirkungen hat oder eine Mockito-Ausnahme auslösen wird. Und ja, wenn Sie sich über die Methode eines Spions lustig machen, den Sie benutzen .when (service) .serviceMethod(); ' Syntax. –

0

Schließlich eine Lösung gefunden: Komponententests für ein Spring-Projekt zu erstellen ist schwieriger als ich erwartet habe (zumindest mit Mockito Framework), also habe ich eine Lösung gefunden, die auch einige Spring Annotations

verwendetDas ist also mein neuer Arbeits Test:

@MockBean 
Dao dao; 

@Autowired 
Service service; 

@Test(expected=MyException.class) 
public void shouldReturnMyException throws MyException { 
    when(dao.dao_method()).thenThrow(new ExceptionFromDaoMethod()); 
}