В чем разница между Mockito Matchers isA, any, eq и тем же?

меня смущает то, что разница между ними и какой из них выбрать в случае чего. Какая-то разница может быть очевидной, например any и eq, но я включаю их все, чтобы быть уверенным.

я задаюсь вопросом об их различиях, потому что я столкнулся с этой проблемой: У меня есть этот метод POST в классе контроллера

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

и хотел бы выполнить модульный тест на этом контроллере. У меня две версии. Первый из них простой, как это

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

но я хотел использовать подход MockMvc, как этот

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

оба работают хорошо. Но я хотел моего someServiceMock.doSomething() в подходе MockMvc для получения req, или, по крайней мере, объект, который имеет те же значения переменных в качестве req (не просто Request класс), и return res, как и первый. Я знаю, что невозможно использовать подход MockMvc (или это так?), потому что объект, переданный в фактическом вызове, всегда отличается от объекта прошел в макете. Могу ли я достичь этого? Или это вообще имеет смысл? Или я должен быть удовлетворен, используя any(Request.class)? Я пытался eq, same, но все они терпят неудачу.

спасибо заранее. Надеюсь, я хорошо объяснился.

2 ответов


  • any() абсолютно ничего не проверяет. В Mockito 1.x,any(T.class) также проверяет абсолютно ничего, но также сохраняет вас (до Java 8).

    это связано с изменением в Mockito 2.0 и за пределы, когда any(T.class) поделиться isA семантика означает " любой T" или правильно "любой экземпляр типа T". any() все равно ничего не проверит.

  • isA(T.class) проверяет, что аргумент instanceof T, подразумевается, что он не является нулевым.

  • same(obj) проверяет, что аргумент является тем же экземпляром,obj, таких, что arg == obj - это правда.

  • eq(obj) проверяет, что аргумент равен obj по его equals метод. Это также поведение, если вы передаете реальные значения без использования сопоставителей.

    обратите внимание, что если equals переопределено, вы увидите объект по умолчанию.равная реализация, которая будет иметь такое же поведение, как same(obj).

Если вам нужна более точная настройка, вы можете использовать адаптер для своего собственного предиката:

  • Для Mockito 1.x, Используйте argThat с пользовательским Hamcrest Matcher<T> это выбирает именно те объекты, которые вам нужны.
  • для Mockito 2.0 и за его пределами используйте Matchers.argThat с пользовательским org.mockito.ArgumentMatcher<T> или MockitoHamcrest.argThat с пользовательским Hamcrest Matcher<T>.

если ваш запрос.класс реализует equals, тогда вы можете использовать eq ():

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

выше , когда активировать на

fooService.fooFxn(otherBar);

если

otherBar.equals(bar);

альтернативно, если вы хотите, чтобы макет работал для некоторого другого подмножества ввода (например, все бары с баром.getBarLength ()>10), вы можете создать Сопоставитель. Я не вижу этот шаблон слишком часто, поэтому обычно я создаю сопоставление как частный класс:

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

вы бы тогда используйте этот matcher следующим образом:

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

надеюсь, что это поможет!