Quelle est la différence entre Mockito Matchers isA, any, eq et same?

Je suis confus sur quelle est la différence entre eux, et lequel choisir dans quel cas. Une différence peut sembler évidente, comme dans any eq , mais je les inclue tous pour en être sûr.

Je m’interroge sur leurs différences car j’ai rencontré ce problème: j’ai cette méthode POST dans une classe de contrôleur

 public Response doSomething(@ResponseBody Request request) { return someService.doSomething(request); } 

Et voudrait effectuer un test unitaire sur ce contrôleur. J’ai deux versions. Le premier est simple, comme ça

 @Test public void testDoSomething() { //initialize ObjectMapper mapper //initialize Request req and Response res when(someServiceMock.doSomething(req)).thenReturn(res); Response actualRes = someController.doSomething(req); assertThat(actualRes, is(res)); } 

Mais je voulais utiliser une approche MockMvc, comme celle-ci

 @Test public void testDoSomething() { //initialize ObjectMapper mapper //initialize Request req and Response res when(someServiceMock.doSomething(any(Request.class))).thenReturn(res); mockMvc.perform(post("/do/something") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsSsortingng(req)) ) .andExpect(status().isOk()) .andExpect(jsonPath("$message", is("done"))); } 

Les deux fonctionnent bien. Mais je voulais que someServiceMock.doSomething() dans l’approche MockMvc reçoive req , ou au moins un object ayant les mêmes valeurs de variable que req (pas n’importe quelle classe Request ), et renvoie res , comme le premier. Je sais qu’il est impossible d’utiliser l’approche MockMvc (ou l’est-il?), Car l’object transmis dans l’appel réel est toujours différent de l’object transmis dans la simulation. Y a-t-il un moyen d’y parvenir? Ou est-ce même logique de faire cela? Ou devrais-je être satisfait en utilisant any(Request.class) ? J’ai essayé eq , same , mais tous échouent.

Merci d’avance. J’espère que je me suis bien expliqué.

  • any() vérifie absolument rien. Dans Mockito 1.x, any(T.class) vérifie absolument rien, mais vous évite également une dissortingbution (avant Java 8).

    Cela est dû au changement dans Mockito 2.0 et au-delà , quand any(T.class) partagera la sémantique any(T.class) pour signifier “tout T ” ou proprement “toute instance de type T “. any() vérifiera absolument rien.

  • isA(T.class) vérifie que l’argument instanceof T , ce qui implique qu’il est non nul.

  • same(obj) vérifie que l’argument est la même instance que obj , tel que arg == obj est vrai.

  • eq(obj) vérifie que l’argument est égal à obj selon sa méthode equals . C’est aussi le comportement si vous passez des valeurs réelles sans utiliser de matchers.

    Notez que sauf si equals est remplacé, vous verrez l’implémentation Object.equals par défaut, qui aurait le même comportement que same(obj) .

Si vous avez besoin d’une personnalisation plus précise, vous pouvez utiliser un adaptateur pour votre propre prédicat:

  • Pour Mockito 1.x, utilisez argThat avec un Hamcrest Matcher Matcher qui sélectionne exactement les objects dont vous avez besoin.
  • Pour Mockito 2.0 et les versions ultérieures, utilisez Matchers.argThat avec un org.mockito.ArgumentMatcher personnalisé org.mockito.ArgumentMatcher ou MockitoHamcrest.argThat avec un Hamcrest Matcher personnalisé Matcher .

Si votre Request.class implémente des équivalents, vous pouvez utiliser eq ():

 Bar bar = getBar(); when(fooService.fooFxn(eq(bar)).then... 

Le ci dessus quand serait activé sur

 fooService.fooFxn(otherBar); 

si

 otherBar.equals(bar); 

Sinon, si vous voulez que la maquette fonctionne pour un autre sous-ensemble d’entrées (par exemple, toutes les mesures avec Bar.getBarLength ()> 10), vous pouvez créer un Matcher. Je ne vois pas ce modèle trop souvent, donc je crée généralement Matcher en tant que classe privée:

 private static class BarMatcher extends BaseMatcher{ ...//constructors, descriptions, etc. public boolean matches(Object otherBar){ //Checks, casts, etc. return otherBar.getBarLength()>10; } } 

Vous utiliseriez alors ce matcher comme suit:

 when(fooService.fooFxn(argThat(new BarMatcher())).then... 

J’espère que cela pourra aider!