1
votes

I am having problems getting jMock to correctly match the expectation that I want it to. I have a method that I want to call on a mock object multiple times with two different parameters. I want the method to return a different value for each parameter. Unfortunately, when I attempt to call the method with the second parameter, the result is a NoSuchMethodError for org.hamcrest.Matcher.describeMismatch.

Here is a sample of what I am trying to do.

import static org.hamcrest.Matchers.*;
import org.jmock.Expectations;
import static org.jmock.Expectations.*;
import org.jmock.auto.Mock;
import org.jmock.integration.junit4.JUnitRuleMockery;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;

public class JMockTest {
    interface A {
        int foo(int x);
    }

    @Rule
    public final JUnitRuleMockery context = new JUnitRuleMockery();
    @Mock
    private A a;

    @Test
    public void testFoo() {
        context.checking(new Expectations() {{
            allowing(a).foo(1); will(returnValue(1));
            allowing(a).foo(2); will(returnValue(2));
        }});
        assertThat(a.foo(1), is(1));
        assertThat(a.foo(2), is(2));
    }
}

I am using jMock 2.6.0 and JUnit 4.10. I am using hamcrest-core-1.3.jar, hamcrest-library-1.3.jar, jmock-2.6.0.jar, and jmock-junit4-2.6.0.jar.

If I change the allowing calls to oneOf calls, then the test passes. The jMock cookbook (http://jmock.org/parameters.html) gives an example very similar to mine, so I would expect that I should be able to use allowing in this case.

Here is the output when I try to run my test.

Testcase: testFoo(JMockTest):   Caused an ERROR
org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
    at org.jmock.internal.matcher.AllParametersMatcher.matchesParameter(AllParametersMatcher.java:61)
    at org.jmock.internal.matcher.AllParametersMatcher.matchesParameters(AllParametersMatcher.java:47)
    at org.jmock.internal.matcher.AllParametersMatcher.matchesSafely(AllParametersMatcher.java:31)
    at org.jmock.internal.matcher.AllParametersMatcher.matchesSafely(AllParametersMatcher.java:13)
    at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
    at org.jmock.internal.InvocationExpectation.matches(InvocationExpectation.java:147)
    at org.jmock.internal.InvocationDispatcher.dispatch(InvocationDispatcher.java:80)
    at org.jmock.Mockery.dispatch(Mockery.java:231)
    at org.jmock.Mockery.access$100(Mockery.java:29)
    at org.jmock.Mockery$MockObject.invoke(Mockery.java:271)
    at org.jmock.internal.InvocationDiverter.invoke(InvocationDiverter.java:27)
    at org.jmock.internal.FakeObjectMethods.invoke(FakeObjectMethods.java:38)
    at org.jmock.internal.SingleThreadedPolicy$1.invoke(SingleThreadedPolicy.java:21)
    at org.jmock.lib.JavaReflectionImposteriser$1.invoke(JavaReflectionImposteriser.java:33)
    at $Proxy6.foo(Unknown Source)
1

1 Answers

0
votes

It turns out that the problem was with the jars that I was including. The JUnit jar contains some hamcrest classes that are in conflict with classes in the hamcrest jars. I was able to rearrange the classpath so that the hamcrest jars were added before the JUnit jar.