You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was trying to build a function that can return a mock of any interface extending a generic parent interface. The extending interface specifies the generic parameters.
I've found that if the extending interface does not re-declare the method, then it works as expected (the mock object exhibits mocked behavior when the method is invoked.)
If the extending interface does re-declare the method, then the mock object does not exhibit the mocked behavior when the method is invoked on the mock.
Hopefully the example below helps clarify:
package mockitotest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.mockito.Mockito;
// Test case demonstrating a perceived defect in Mockito
public class MockBuilderTest {
// 1. Create an object to use for a return type
public class ReturnType {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// 2. Define an interface
public interface OriginalInterface<N,O> {
// contains a templated method
O doSomething(N n);
};
// 3. Create an extending interface which specifies the templated arguments
public interface ExtendingInterfaceObject extends OriginalInterface<String, ReturnType> {
// 4. The method would be inherited, but I re-state it, mostly to add additional
// documentation inside the interface
@Override
ReturnType doSomething(String n);
};
// 5. For demonstration purposes, create an extending interface which does specify the
// templated arguments, but does not re-state the method
public interface ExtendingInterfaceObjectNoRedef extends OriginalInterface<String, ReturnType> {}
// A function to build a mocked object, the type of object is specified as a method argument
// the value that should be returned (O) is also provided as an argument
<N,O,T extends OriginalInterface<N,O>> T buildMock(Class<T> cls, final O o) {
Class<N> n = null;
// create a mocked object of the specified class
T t = Mockito.mock(cls, Mockito.withSettings().verboseLogging());
// override the doSomething function to return the desired value
Mockito.when(t.doSomething(Mockito.any(n))).thenReturn(o);
return t;
}
// Example A: I would expect that 'r' be returned by the resulting mocked object, but
// mockito doesn't seem to match up the invocation with an overriden method
@Test
public void testBuild_object() {
ReturnType r = new ReturnType();
r.setName("testBuild");
ExtendingInterfaceObject i = buildMock(ExtendingInterfaceObject.class, r);
assertTrue(i instanceof ExtendingInterfaceObject);
assertEquals(r, i.doSomething("TEST"));
}
// Example B: like example A, but this uses the extending interface which *does not*
// re-state the method. This example completes successfully.
@Test
public void testBuild_object_no_redef() {
ReturnType r = new ReturnType();
r.setName("testBuild");
ExtendingInterfaceObjectNoRedef i = buildMock(ExtendingInterfaceObjectNoRedef.class, r);
assertTrue(i instanceof ExtendingInterfaceObjectNoRedef);
assertEquals(r, i.doSomething("TEST"));
}
}
The text was updated successfully, but these errors were encountered:
I was trying to build a function that can return a mock of any interface extending a generic parent interface. The extending interface specifies the generic parameters.
I've found that if the extending interface does not re-declare the method, then it works as expected (the mock object exhibits mocked behavior when the method is invoked.)
If the extending interface does re-declare the method, then the mock object does not exhibit the mocked behavior when the method is invoked on the mock.
Hopefully the example below helps clarify:
The text was updated successfully, but these errors were encountered: