2015-06-17 24 views
18

Jestem zdezorientowany, jaka jest między nimi różnica, a którą wybrać w takim przypadku. Niektóre różnice mogą być oczywiste, jak na przykład any i eq, ale uwzględniam je wszystkie tylko po to, aby mieć pewność.Jaka jest różnica pomiędzy Matrix Matrix isA, any, eq i same?

Zastanawiam o dzielących ich różnic, ponieważ natknąłem tego problemu: mam tej metody POST w klasie Controller

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

i chciałbyś wykonać test jednostki na tym kontrolerze. Mam dwie wersje. Pierwszym z nich jest prosta, jak to

@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)); 
} 

Ale chciałem użyć podejście MockMvc, jak ten jeden

@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"))); 
} 

Oba działają dobrze. Ale chciałem, aby mój someServiceMock.doSomething() w podejściu MockMvc otrzymał req, lub przynajmniej obiekt, który ma te same wartości zmiennych co req (nie tylko jakakolwiek klasa Request) i zwróci res, podobnie jak pierwsza. Wiem, że to niemożliwe przy użyciu podejścia MockMvc (lub jest to?), Ponieważ obiekt przekazany w faktycznym wywołaniu jest zawsze inny niż obiekt przekazany w sztuczce. Czy mimo to mogę to osiągnąć? A może ma to jakiś sens? Czy powinienem być zadowolony używając any(Request.class)? Próbowałem już eq, same, ale wszystkie z nich zawiodły.

Z góry dziękuję. Mam nadzieję, że wyjaśniłem się dobrze.

Odpowiedz

40
  • any() nie sprawdza absolutnie niczego. W Mockito 1.x, any(T.class) sprawdza również absolutnie nic, ale również zapisuje ci rzut (przed Java 8).

    This is due to change in Mockito 2.0 and beyond, gdy any(T.class) podzieli isA semantykę oznaczają „wszelkie T” lub „właściwie żadnej instancji typu T”. any() będzie nadal sprawdzać absolutnie nic.

  • isA(T.class) sprawdza, czy argument instanceof T sugeruje, że ma wartość inną niż null.

  • same(obj) sprawdza, czy argument jest tym samym wystąpieniem co obj, tak że arg == obj jest prawdziwe.

  • eq(obj) sprawdza, czy argument jest równy obj zgodnie z jego metodą equals. Jest to także zachowanie, jeśli przekazujesz prawdziwe wartości bez używania dopasowań.

    Należy zauważyć, że jeśli nie zostanie nadpisane equals, zobaczysz domyślną implementację Object.equals, która będzie miała takie samo zachowanie, jak same(obj).

Jeśli potrzebujesz bardziej dokładne dostosowanie, można użyć adaptera do własnego orzecznika:

  • Dla Mockito 1.x użyj argThat ze zwyczajem Hamcrest Matcher<T> że wybiera dokładnie te obiekty, których potrzebujesz .
  • Dla Mockito 2.0 i późniejszych użyj Matchers.argThat z niestandardowym org.mockito.ArgumentMatcher<T> lub MockitoHamcrest.argThat z niestandardowym Hamcrest Matcher<T>.
2

Jeśli Request.class narzędzia równa, a następnie można użyć eq():

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

Powyższy gdy by aktywować

fooService.fooFxn(otherBar); 

jeśli

otherBar.equals(bar); 

Alternatywnie, jeśli chcesz, aby udawało się pracować dla jakiegoś innego podzbioru inpu t (na przykład wszystkie paski z Bar.getBarLength()> 10), możesz utworzyć Matchera. Nie widzę ten wzór zbyt często, więc zazwyczaj tworzę z Matcher jako prywatny klasy:

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

Można by następnie użyć tego matcher następująco:

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

nadzieję, że pomoże!