Mockito Matchers之间有什么区别是A,any,eq和同样的?

我很困惑他们之间有什么区别,在哪种情况下选择哪一个。 有些差异可能很明显,比如anyeq ,但我把它们都包括在内只是为了确定。

我想知道他们之间的差异,因为我遇到了这个问题:我在Controller类中有这个POST方法

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

并希望在该控制器上执行unit testing。 我有两个版本。 第一个是简单的,就像这样

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

两者都运作良好。 但我希望我的MockMvc方法中的someServiceMock.doSomething()接收req ,或者至少是一个与req (不仅仅是任何Request类)具有相同变量值的对象,并返回res ,就像第一个一样。 我知道使用MockMvc方法是不可能的(或者是吗?),因为实际调用中传递的对象总是与mock中传递的对象不同。 无论如何我能做到吗? 或者这样做甚至有意义吗? 或者我应该满意使用any(Request.class) ? 我已经尝试过eq ,但是所有这些都失败了。

先谢谢你。 我希望我能很好地解释自己。

  • any()绝对没有检查。 在Mockito 1.x中, any(T.class)也绝对不会检查任何东西,但也会为你节省一个演员阵容(在Java 8之前)。

    这是由于Mockito 2.0及更高版本的变化 ,当any(T.class)isA语义分享为“任何T ”或正确“任何类型T实例”时。 any()仍然会检查一切。

  • isA(T.class)检查参数instanceof T ,暗示它是非null。

  • same(obj)检查参数是否与obj相同,这样arg == obj为true。

  • eq(obj)根据equals方法检查参数是否等于obj 。 如果您在不使用匹配器的情况下传递实际值,这也是一种行为。

    请注意,除非重写equals ,否则您将看到默认的Object.equals实现,它具有与same(obj)相同的行为。

如果需要更精确的自定义,可以使用适配器作为自己的谓词:

  • 对于Mockito 1.x,使用带有自定义Hamcrest Matcher argThat ,可以精确选择所需的对象。
  • 对于Mockito 2.0及更高版本, org.mockito.ArgumentMatcher与自定义org.mockito.ArgumentMatcherMockitoHamcrest.argThat与自定义Hamcrest Matcher

如果您的Request.class实现了equals,那么您可以使用eq():

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

以上什么时候会激活

 fooService.fooFxn(otherBar); 

如果

 otherBar.equals(bar); 

或者,如果你想让mock用于输入的其他一些子集(例如,所有Bar都有Bar.getBarLength()> 10),你可以创建一个Matcher。 我不经常看到这种模式,所以通常我将Matcher创建为私有类:

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

然后,您将使用此匹配器,如下所示:

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

希望有所帮助!