Mockito Matchers isA、any、eq 和 same 有什么区别?

时间:2023-05-03
本文介绍了Mockito Matchers isA、any、eq 和 same 有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我对它们之间的区别以及在哪种情况下选择哪个感到困惑.有些区别可能很明显,例如 anyeq,但我将它们都包括在内只是为了确定.

I am confused on what's the difference between them, and which one to choose in which case. Some difference might be obvious, like any and eq, but I'm including them all just to be sure.

我想知道它们的区别,因为我遇到了这个问题:我在 Controller 类中有这个 POST 方法

I wonder about their differences because I came across this problem: I have this POST method in a Controller class

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

并且想对该控制器执行单元测试.我有两个版本.第一个是简单的,像这样

And would like to perform a unit test on that controller. I have two versions. The first one is the simple one, like this

@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 方法,比如这个

But I wanted to use a MockMvc approach, like this one

@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 类),并返回 res,就像第一个一样.我知道使用 MockMvc 方法是不可能的(或者是吗?),因为在实际调用中传递的对象总是与在模拟中传递的对象不同.无论如何我可以做到这一点吗?或者这样做是否有意义?或者我应该对使用 any(Request.class) 感到满意吗?我试过eqsame,但都失败了.

Both work well. But I wanted my someServiceMock.doSomething() in the MockMvc approach to receive req, or at least an object that has the same variable values as req (not just any Request class), and return res, just like the first. I know that it's impossible using the MockMvc approach (or is it?), because the object passed in the actual call is always different from the object passed in the mock. Is there anyway I can achieve that? Or does it even make sense to do that? Or should I be satisfied using any(Request.class)? I've tried eq, same, but all of them fail.

推荐答案

  • any() 绝对不检查任何内容.从 Mockito 2.0 开始,any(T.class) 共享 isA 语义以表示任何 T";或正确地T 类型的任何实例".

    • any() checks absolutely nothing. Since Mockito 2.0, any(T.class) shares isA semantics to mean "any T" or properly "any instance of type T".

      这是与 Mockito 1.x 相比的一个变化,其中 any(T.class) 完全没有检查但在 Java 8 之前保存了一个强制转换:任何类型的对象,对于给定的类不是必需的.提供类参数只是为了避免强制转换."

      This is a change compared to Mockito 1.x, where any(T.class) checked absolutely nothing but saved a cast prior to Java 8: "Any kind object, not necessary of the given class. The class argument is provided only to avoid casting."

      isA(T.class) 检查参数 instanceof T 是否为非空.

      same(obj) 检查参数是否引用与 obj 相同的实例,使得 arg == obj 为真.

      same(obj) checks that the argument refers to the same instance as obj, such that arg == obj is true.

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

      eq(obj) checks that the argument equals obj according to its equals method. This is also the behavior if you pass in real values without using matchers.

      请注意,除非 equals 被覆盖,否则您将看到默认的 Object.equals 实现,其行为与 same(obj) 相同.

      Note that unless equals is overridden, you'll see the default Object.equals implementation, which would have the same behavior as same(obj).

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

      If you need more exact customization, you can use an adapter for your own predicate:

      • 对于 Mockito 1.x,请使用 argThat 带有自定义 Hamcrest Matcher,可以准确选择您需要的对象.
      • 对于 Mockito 2.0 及更高版本,请使用 Matchers.argThat 与自定义 org.mockito.ArgumentMatcherMockitoHamcrest.argThat使用自定义 Hamcrest Matcher<T>.
      • For Mockito 1.x, use argThat with a custom Hamcrest Matcher<T> that selects exactly the objects you need.
      • For Mockito 2.0 and beyond, use Matchers.argThat with a custom org.mockito.ArgumentMatcher<T>, or MockitoHamcrest.argThat with a custom Hamcrest Matcher<T>.

      您也可以使用 refEq,它使用reflection来确认对象相等;Hamcrest 与公共 bean 的 SamePropertyValuesAs 有类似的实现-样式属性.请注意,在 GitHub issue #1800 上建议弃用和删除 refEq,并且在那个问题中,您可能更喜欢 eq 来更好地为您的类提供更好的封装,而不是它们的平等感.

      You may also use refEq, which uses reflection to confirm object equality; Hamcrest has a similar implementation with SamePropertyValuesAs for public bean-style properties. Note that on GitHub issue #1800 proposes deprecating and removing refEq, and as in that issue you might prefer eq to better give your classes better encapsulation over their sense of equality.

      这篇关于Mockito Matchers isA、any、eq 和 same 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!