web-dev-qa-db-fra.com

Lancer vérifié Exceptions de mock avec Mockito

J'essaie de demander à l'un de mes objets simulés de lancer 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 documentation Mockito , ils n'utilisent que RuntimeException, n'est-il pas possible de lancer des exceptions vérifiées à partir d'un objet fictif avec Mockito?

129
Arthur Maltson

Vérifiez l'API Java pour List . La méthode get (int) est déclarée pour ne lancer que l'exception IndexOutOfBoundException qui étend RuntimeException. Vous essayez de dire à Mockito de lancer une exception qui n'est pas valide pour être levée par cet appel de méthode particulier.

Pour clarifier davantage. L'interface List ne permet pas de lever une exception vérifiée à partir de la méthode get () et c'est pourquoi Mockito échoue. Lorsque vous créez la liste simulée, Mockito utilise la définition de List.class pour créer sa maquette. Le comportement que vous spécifiez avec la fonction when(list.get(0)).thenThrow(new SomeException()) ne correspond pas à la signature de la méthode dans List.class, donc Mockito échoue. Si vous voulez vraiment faire cela, demandez alors à Mockito de lancer une new RuntimeException() ou, mieux encore, une new ArrayIndexOutOfBoundsException() puisque l’API spécifie qu’il s’agit de la seule exception valide à lancer.

177
John Engelman

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

Par exemple, le travail suivant fonctionne (et ne lance pas un MockitoException mais jette en fait un vérifié Exception comme requis ici) en utilisant BDDMockito:

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

L'équivalent pour Mockito ordinaire serait d'utiliser la méthode doAnswer

59
Deepak