294 votes

Lancer des exceptions vérifiées à partir d'objets fantaisie avec Mockito

J'essaie de faire en sorte que l'un de mes objets simulés lance une Exception vérifiée lorsqu'une méthode particulière est appelée. J'essaie ce qui suit.

@Test(expectedExceptions = SomeException.class)
public void throwCheckedException() {
    List<String> list = mock(List.class);
    when(list.get(0)).thenThrow(new SomeException());
    String test = list.get(0);
}

public class SomeException extends Exception {
}

Cependant, cela produit l'erreur suivante.

org.testng.TestException: 
Expected exception com.testing.MockitoCheckedExceptions$SomeException but got org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!
Invalid: com.testing.MockitoCheckedExceptions$SomeException

En regardant la Documentation de Mockito ils n'utilisent que des RuntimeException Il n'est donc pas possible de lancer des exceptions vérifiées à partir d'un objet fantaisie avec Mockito ?

357voto

Thijs van Kampen Points 13

Vérifier l'API Java pour Liste .
Les get(int index) est déclarée pour lancer uniquement la méthode IndexOutOfBoundException qui étend RuntimeException .
Vous essayez de dire à Mockito de lancer une exception SomeException() c'est-à-dire n'est pas valide pour être lancé par cet appel de méthode particulier .

Pour plus de clarté.
Les Liste ne prévoit pas qu'une exception vérifiée puisse être lancée à partir de l'interface get(int index) et c'est pourquoi Mockito échoue.
Lorsque vous créez le Liste moquée Mockito utilisera l'élément définition de la liste .class pour créer son mock.

Le comportement que vous spécifiez avec l'option when(list.get(0)).thenThrow(new SomeException()) ne correspond pas à la signature de la méthode dans List API parce que get(int index) ne lance pas la méthode SomeException() Mockito échoue donc.

Si vous voulez vraiment le faire, demandez à Mockito de lancer une commande new RuntimeException() ou, mieux encore, lancez un new ArrayIndexOutOfBoundsException() puisque l'API spécifie que c'est la seule exception valide à lancer.

207voto

Deepak Points 1

Une solution de contournement consiste à utiliser un willAnswer() méthode.

Par exemple, l'exemple suivant fonctionne (et ne provoque pas d'erreur de saisie) MockitoException mais lance en réalité un Exception comme requis ici) en utilisant BDDMockito :

given(someObj.someMethod(stringArg1)).willAnswer( invocation -> { throw new Exception("abc msg"); });

L'équivalent pour Mockito simple serait d'utiliser l'option doAnswer méthode

31voto

Kevin ABRIOUX Points 6237

Il existe une solution avec Kotlin :

given(myObject.myCall()).willAnswer {
    throw IOException("Ooops")
}

D'où vient le don

import org.mockito.BDDMockito.given

24voto

David Moles Points 7669

Notez qu'en général, Mockito fait permettent de lancer des exceptions vérifiées tant que l'exception est déclarée dans la signature du message. Par exemple, si l'on donne à

class BarException extends Exception {
  // this is a checked exception
}

interface Foo {
  Bar frob() throws BarException
}

il est légal d'écrire :

Foo foo = mock(Foo.class);
when(foo.frob()).thenThrow(BarException.class)

Toutefois, si vous lancez une exception vérifiée non déclarée dans la signature de la méthode, par exemple

class QuxException extends Exception {
  // a different checked exception
}

Foo foo = mock(Foo.class);
when(foo.frob()).thenThrow(QuxException.class)

Mockito échouera au moment de l'exécution avec un message générique quelque peu trompeur :

Checked exception is invalid for this method!
Invalid: QuxException

Cela peut vous amener à penser que les exceptions vérifiées en général ne sont pas supportées, mais en fait Mockito essaie seulement de vous dire que cette l'exception vérifiée n'est pas valide pour cette méthode .

8voto

Alok Gupta Points 545

Cela fonctionne pour moi en Kotlin :

when(list.get(0)).thenThrow(new ArrayIndexOutOfBoundsException());

Note : Lancer toute exception définie autre que Exception()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X