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.
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)partagerisAsémantique pour dire"T" ou bien "une instance de typeT".any()vérifie toujours absolument rien.isA(T.class)vérifie que l'argumentinstanceof T, ce qui implique il est non-nulle.same(obj)vérifie que l'argument est le même exemple queobjtels quearg == objest vraie.eq(obj)vérifie que l'argument est égal àobjselon sesequalsméthode. C'est aussi le comportement si vous passez dans les vraies valeurs, sans l'aide de rapprochement.notez que sauf si
equalsest remplacé, vous verrez l'Objet par défaut.mise en œuvre égale, qui aurait le même comportementsame(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
argThatavec un custom HamcrestMatcher<T>qui sélectionne exactement les objets dont vous avez besoin. - Pour Mockito 2.0 et au-delà, utiliser
Matchers.argThatavec un customorg.mockito.ArgumentMatcher<T>, ouMockitoHamcrest.argThatavec un custom HamcrestMatcher<T>.
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!