Open
Description
A bit subtle, but definitely confusing. If you reify a generic method in a sub-interface, then Java considers that a new declaredMethod. MethodMatcher only considers if the method called is .equals, rather than compatible...
... although I really don't know what compatible means. Anyhoo, this demonstrates the problem -
import org.jmock.Expectations;
import org.jmock.integration.junit4.JUnitRuleMockery;
import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class JMockMethodMatchingTest
{
@Rule public JUnitRuleMockery context = new JUnitRuleMockery();
private static interface Function<F, T> {
T apply(F input);
}
private static interface StringFunction extends Function<String, String> {
@Override public String apply(String input);
}
private Function<String, String> mockedFunction = context.mock(Function.class);
private StringFunction mockedStringFunction = context.mock(StringFunction.class);
@Test
public void test() throws Exception
{
context.checking(new Expectations() {{
allowing (mockedStringFunction).apply("alice");
will (returnValue("bob"));
allowing (mockedFunction).apply("alice");
will (returnValue("bob"));
}});
assertEquals("bob", mockedFunction.apply("alice"));
assertEquals("bob", mockedStringFunction.apply("alice"));
assertEquals("bob", apply(mockedFunction, "alice"));
assertEquals("bob", apply(mockedStringFunction, "alice"));
// java.lang.AssertionError: unexpected invocation: stringFunctor.apply("alice")
}
private String apply(Function<String, String> f, String arg) {
return f.apply(arg);
}
}