Quelle est la différence entre Mockito Matchers isA, any, eq, et même?

Je ne sais pas quelle est la différence entre eux, et lequel choisir dans quel cas. Une différence pourrait être évidente, comme any et eq, mais je les Inclus tous juste pour être sûr.

Je m'interroge sur leurs différences parce que je suis tombé sur 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 souhaitez effectuer un test unitaire sur ce contrôleur. J'ai deux versions. Le premier est le simple, comme ce

@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 un MockMvc approche, 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.writeValueAsString(req))
    )
            .andExpect(status().isOk())
            .andExpect(jsonPath("$message", is("done")));
}

les deux fonctionnent bien. Mais je voulais que mon someServiceMock.doSomething() dans l'approche MockMvc pour recevoir req, ou au moins un objet qui a les mêmes valeurs de la variable req (pas n'importe quel Request classe), et retour res, comme la première. Je sais que c'est impossible avec L'approche MockMvc (ou est-ce le cas?), parce que l'objet passé dans l'appel est toujours différente de l'objet passé dans le simulacre. Est-il de toute façon je peux réaliser cela? Ou est-ce logique de faire ça? Ou devrais-je être satisfait en utilisant <!--10? J'ai essayé eq,same, mais échoue.

je vous Remercie à l'avance. J'espère que j'ai expliqué moi-même.

27
demandé sur cegas 2015-06-17 14:18:06

2 réponses

  • any() ne vérifie absolument rien. À Mockito 1.x,any(T.class) vérifie aussi absolument rien mais enregistre aussi un cast (avant Java 8).

    Ceci est dû au changement dans Mockito 2.0 et au-delà lorsque any(T.class) partager isA sémantique pour dire"T" ou bien "une instance de type T". any() vérifie toujours absolument rien.

  • isA(T.class) vérifie que l'argument instanceof T, ce qui implique il est non-nulle.

  • same(obj) vérifie que l'argument est le même exemple que obj tels que arg == obj est vraie.

  • eq(obj) vérifie que l'argument est égal à obj selon ses equals méthode. C'est aussi le comportement si vous passez dans les vraies valeurs, sans l'aide de rapprochement.

    notez que sauf si equals est remplacé, vous verrez l'Objet par défaut.mise en œuvre égale, qui aurait le même comportement 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 custom Hamcrest Matcher<T> qui sélectionne exactement les objets dont vous avez besoin.
  • Pour Mockito 2.0 et au-delà, utiliser Matchers.argThat avec un custom org.mockito.ArgumentMatcher<T>, ou MockitoHamcrest.argThat avec un custom Hamcrest Matcher<T>.
52
répondu Jeff Bowman 2017-05-23 12:02:42

si vous le souhaitez.classe implémente des égaux, alors vous pouvez utiliser l'égaliseur():

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

quand activer

fooService.fooFxn(otherBar);

si

otherBar.equals(bar);

alternativement, si vous voulez que la simulation fonctionne pour un autre sous-ensemble d'entrées (par exemple, toutes les barres avec barre.getBarLength ()>10), vous pouvez créer un Matcher. Je ne vois pas ce modèle, trop souvent, donc j'ai créer la Correspondance privée de la classe:

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

vous utiliseriez alors cette correspondance comme suit:

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

j'Espère que ça aide!

2
répondu Alex Pruss 2015-06-17 11:55:33