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)
partagerisA
sé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 queobj
tels quearg == obj
est vraie.eq(obj)
vérifie que l'argument est égal àobj
selon sesequals
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 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
argThat
avec un custom HamcrestMatcher<T>
qui sélectionne exactement les objets dont vous avez besoin. - Pour Mockito 2.0 et au-delà, utiliser
Matchers.argThat
avec un customorg.mockito.ArgumentMatcher<T>
, ouMockitoHamcrest.argThat
avec 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!