Cesar Farell, 3 November 2005
Having trouble mocking up the getPrimaryKey() method on an entity?
Here’s what I first tried (how we “normally” do it):
Mock mock = new Mock(PackagingTypeLocal.class); mock.expects(once()) .method("getPrimaryKey") .withNoArguments() .will(returnValue(packagingTypeCode));
But then when I run the test that uses this code, I run into the following assertion failure, coming from jMock:
org.jmock.core.DynamicMockError: mockPackagingTypeLocal: no match found Invoked: javax.ejb.EJBLocalObject.getPrimaryKey() Allowed: expected once and has been invoked: getPrimaryKey, (no arguments), returns <DISP> at org.jmock.core.AbstractDynamicMock.mockInvocation(Unknown Source) at org.jmock.core.CoreMock.invoke(Unknown Source) at $Proxy0.getPrimaryKey(Unknown Source)
It looks like jMock is complaining that about the fact that I’m trying to invoke a method on a super-type (EJBLocalObject) instead of a method that is defined by the specific interface that it is mocking (in this case, PackagingTypeLocal).
It turns out that the following works just fine:
mock.expects(exactly(1)) .method("getPrimaryKey") .withNoArguments() .will(returnValue(packagingTypeCode));
If, instead of using the invocation builder approach directly off of the mock, as above, I use the following:
Mock mock = new Mock(PackagingTypeLocal.class); InvocationMocker invocationMocker = new InvocationMocker(); invocationMocker.addMatcher(new MethodNameMatcher("getPrimaryKey")); invocationMocker.addMatcher(new InvokeCountMatcher(1)); invocationMocker.setStub(returnValue(packagingTypeCode)); mock.addInvokable(invocationMocker);
which is the same as what was specified above (but explicitly assembling it “by hand”), then it also works.
But, if I use
then I get the problem again.
InvokeOnceMatcher is buggy. It’s more expressive, so I’ll try to use it whenever I can. If I see this sort of problem, I’ll switch to using InvokeCountMatcher with a count of 1.