web-dev-qa-db-fra.com

mockito: comment démasquer une méthode?

J'ai une classe JUnit avec différentes méthodes pour effectuer différents tests.

J'utilise Mockito pour créer un espion sur une instance réelle, puis je remplace une méthode qui n'est pas pertinente pour le test que j'effectue.

Existe-t-il un moyen, juste pour nettoyer après moi au cas où d'autres tests qui s'exécuteraient après mes tests utilisent également les mêmes instances et pourraient exécuter une méthode simulée qu'ils n'ont pas demandé de simuler, pour simuler une méthode?

dis que j'ai un objet espion appelé 'wareHouseSpy'

disons que j'ai outrepassé la méthode isSomethingMissing :

doReturn(false).when(wareHouseSpy).isSomethingMissing()

Quelle sera la bonne façon de passer outre et de ramener les choses à la normale sur l'espion, c'est-à-dire de faire la prochaine invocation de isSomethingMissing pour exécuter la vraie méthode ?

quelque chose comme

doReturn(Mockito.RETURN_REAL_METHOD).when(wareHouseSpy).isSomethingSpy()

ou peut-être

Mockito.unmock(wareHouseSpy)

Qui sait? Je n'ai rien trouvé dans cette zone

Merci!

Assaf

35
user1045740

Je pense

Mockito.reset(wareHouseSpy)

le ferait.

43
Don Roby

Disons que la plupart de vos tests utilisent la réponse tronquée. Ensuite, vous auriez une méthode setUp () qui ressemble à ceci:

@Before
public void setUp() {
  wareHouseSpy = spy(realWarehouse);
  doReturn(false).when(wareHouseSpy).isSomethingMissing();
}

Supposons maintenant que vous souhaitiez annuler la réponse tronquée et utiliser la véritable implémentation dans un test:

@Test
public void isSomethingMissing_useRealImplementation() {
  // Setup
  when(wareHouseSpy.isSomethingMissing()).thenCallRealMethod();

  // Test - Uses real implementation
  boolean result = wareHouseSpy.isSomethingMissing();
}
13
Mike Tran

Cela dépend si vous testez avec TestNG ou JUnit.

  • JUnit crée une nouvelle instance de lui-même pour chaque méthode de test. Vous n'avez essentiellement pas à vous soucier de réinitialiser les simulations.
  • Avec TestNG, vous devez réinitialiser la (les) maquette (s) avec Mockito.reset(mockA, mockB, ...) dans un @BeforeMethod ou un @AfterMethod
9
Brice

Je ne suis peut-être pas en train de suivre mais quand vous avez un vrai objet real:

Object mySpy = spy(real);

Ensuite, pour "nspy" mySpy... utilisez simplement real.

3
Tomasz Nurkiewicz

La manière "normale" consiste à ré-instancier des choses dans votre méthode "setUp". Cependant, si vous avez un véritable objet qui est coûteux à construire pour une raison quelconque, vous pouvez faire quelque chose comme ceci:

public class MyTests {

  private static MyBigWarehouse realWarehouse = new MyBigWarehouse();
  private MyBigWarehouse warehouseSpy;

  @Before
  public void setUp() {
    warehouseSpy = spy(realWarehouse); // same real object - brand new spy!
    doReturn(false).when(wareHouseSpy).isSomethingMissing();
  }

  @Test
  ...

  @Test
  ...

  @Test
  ...
}
2
jhericks

Abordant spécifiquement cette pièce:

Existe-t-il un moyen, juste pour nettoyer après moi au cas où d'autres tests qui s'exécuteraient après mes tests utilisent également les mêmes instances et pourraient exécuter une méthode simulée qu'ils n'ont pas demandé de simuler, pour simuler une méthode?

Si vous utilisez JUnit, la façon la plus simple de le faire est d'utiliser @Before et @After (les autres frameworks ont des équivalents) et recréez l'instance et l'espion pour qu'aucun test ne dépende ou ne soit affecté par ce que vous avez fait sur un autre test. Ensuite, vous pouvez faire la configuration spécifique au test de l'espion/maquette à l'intérieur de chaque test. Si pour une raison quelconque vous ne souhaitez pas recréer l'objet, vous pouvez recréer l'espion. Quoi qu'il en soit, tout le monde commence par un nouvel espion à chaque fois.

0
David H. Clements