简体   繁体   English

模拟方法未返回预期结果

[英]Mocked method doesn't return expected result

I want to mock method mockedMethod(Object object) that accept Object param. 我想模拟接受对象参数的方法mockedMethod(Object object) This object param is created from testedMethod dynamically. 该对象参数是从testedMethod动态创建的。 mockedMethod doesn't return expected result despite of that both objects have the same data, but only different hashCode. 尽管两个对象都具有相同的数据,但是只有不同的hashCode, mockedMethod不会返回预期的结果。

Here is example 这是例子

public void testedMethod() {
    Object object = initObject(); // this object is initialized dynamically
    Long result = mockedMethod(object);
    ...
}

@Test
public void test() {
    Object object = new Object();
    when(api.mockedMethod(object).thenReturn(3L);
    testedMethod();
}

Is there any way how to mock method, that it will be respond with expected result? 有什么方法可以模拟方法,它将以预期的结果响应吗?

Seems like you have two options here: 似乎您在这里有两个选择:

Accept anything 接受任何东西

You can use any() or notNull() , as geoand mentioned in the comments. 您可以使用any()notNull() ,如注释中提到的geoand These define behavior for any parameter ( any ) or any non-null parameter ( notNull ). 这些定义了任何参数( any )或任何非null参数( notNull )的行为。

when(api.mockedMethod(Mockito.any()).thenReturn(3L);
// or
when(api.mockedMethod(Mockito.notNull()).thenReturn(3L);

These static methods return argument matchers , and can be found on the Mockito object inherited from the Matchers object (to keep the APIs a little bit separated). 这些静态方法返回参数的匹配 ,并可以在上找到的Mockito对象从继承匹配器对象 (保持一点点分离的API)。

Write your own custom matcher 编写自己的自定义匹配器

If you need to check that the object matches some custom criteria, you could use a custom ArgumentMatcher object. 如果需要检查对象是否符合某些自定义条件,则可以使用自定义ArgumentMatcher对象。 These objects (otherwise known as Hamcrest matchers, as they come directly from the Hamcrest library) have exactly one boolean method, that returns true if the object matches the condition. 这些对象(也称为Hamcrest匹配器,因为它们直接来自Hamcrest库)仅具有一个布尔方法,如果对象与条件匹配,则返回true。

/** Returns true if the passed object has FooBar anywhere in its class name. */
class HasFooBarInClassName extends ArgumentMatcher<Object> {
  @Override public boolean matches(Object object) {
    return object.getClass().getName().contains("FooBar");
  }
}

when(api.mockedMethod(argThat(new HasFooBarInClassName())).thenReturn(3L);

Bonus: Capturing the Object 奖励:捕获对象

Sometimes your code will need to "capture" the object for additional verification or processing, in a way that Mockito can't do alone. 有时,您的代码将需要“捕获”该对象以进行额外的验证或处理,而Mockito不能单独这样做。 You can use an ArgumentCaptor to help you out there: 您可以使用ArgumentCaptor来帮助您:

ArgumentCaptor<Object> captor = ArgumentCaptor.for(Object.class);
when(api.mockedMethod(any()).thenReturn(3L);
testedMethod();
verify(api).mockedMethod(captor.capture());

// Now you can check the object, as needed, using your own methods.
checkObjectAsNeeded(captor.getValue());

Of course it's not "expected"; 当然,这不是“预期的”。 you're passing a completely different object into the when clause, and the method's using its own from initObject() . 您将一个完全不同的对象传递给when子句,并且该方法使用initObject() You should either inject object into the class under test, or mockedMethod belongs on a service interface, and you should mock that . 您应该注入object到类测试,或mockedMethod所属的业务接口上,你应该嘲笑

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM