简体   繁体   中英

Mocked method doesn't return expected result

I want to mock method mockedMethod(Object object) that accept Object param. This object param is created from testedMethod dynamically. mockedMethod doesn't return expected result despite of that both objects have the same data, but only different hashCode.

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. These define behavior for any parameter ( any ) or any non-null parameter ( 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).

Write your own custom matcher

If you need to check that the object matches some custom criteria, you could use a custom ArgumentMatcher object. 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.

/** 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. You can use an ArgumentCaptor to help you out there:

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() . You should either inject object into the class under test, or mockedMethod belongs on a service interface, and you should mock that .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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