Mockito Matchers isA、any、eq 和 same 之间有什么区别? [英] What's the difference between Mockito Matchers isA, any, eq, and same?
问题描述
我对它们之间的区别以及在这种情况下选择哪一个感到困惑.某些差异可能很明显,例如 any
和 eq
,但为了确定起见,我将它们都包括在内.
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.
我想知道它们的区别,因为我遇到了这个问题:我在控制器类中有这个 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)
感到满意吗?我试过eq
、same
,但都失败了.
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)
sharesisA
semantics to mean "anyT
" or properly "any instance of typeT
".与 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 asobj
, such thatarg == obj
is true.eq(obj)
根据其equals
方法检查参数是否等于obj
.如果您在不使用匹配器的情况下传递实际值,这也是一种行为.eq(obj)
checks that the argument equalsobj
according to itsequals
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 assame(obj)
.如果您需要更精确的自定义,您可以为自己的谓词使用适配器:
If you need more exact customization, you can use an adapter for your own predicate:
- 对于 Mockito 1.x,使用
argThat
带有自定义 HamcrestMatcher
,可以准确选择您需要的对象. - 对于 Mockito 2.0 及更高版本,请使用
Matchers.argThat
带有自定义org.mockito.ArgumentMatcher
或MockitoHamcrest.argThat
使用自定义 HamcrestMatcher
.
- For Mockito 1.x, use
argThat
with a custom HamcrestMatcher<T>
that selects exactly the objects you need. - For Mockito 2.0 and beyond, use
Matchers.argThat
with a customorg.mockito.ArgumentMatcher<T>
, orMockitoHamcrest.argThat
with a custom HamcrestMatcher<T>
.
您也可以使用
refEq
,它使用反射来确认对象相等;Hamcrest 有一个与 SamePropertyValuesAs 类似的实现,用于公共 bean-样式属性.请注意,在 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 removingrefEq
, and as in that issue you might prefereq
to better give your classes better encapsulation over their sense of equality.这篇关于Mockito Matchers isA、any、eq 和 same 之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- 对于 Mockito 1.x,使用