When using EasyMock 2 for testing, typically we need to set up expectations before replay, like this:
expect(mockEmployeeRepository
.findByFirstNameAndLastName("John", "Doe"))
.andReturn(employees);
Sometimes, you don't know exactly what parameter will be used for the expected call, you can instead specify the class of the parameter, such as:
expect(mockEmployeeRepository
.findBySpecification(isA(EmployeeSearchSpecification.class))
.andReturn(employees);
What if you know the exact value of some but not all parameters? I tried the following:
expect(mockEmployeeRepository
.findByDepartmentAndSpecification("HR",
isA(EmployeeSearchSpecification.class))
.andReturn(emplooyees);
Unfortunately, running this test will get the following exception thrown by EasyMock:
java.lang.IllegalStateException: 2 matchers expected, 1 recorded.
The correct way is to wrap the known parameter with an "eq" matcher:
expect(mockEmployeeRepository
.findByDepartmentAndSpecification(eq("HR"),
isA(EmployeeSearchSpecification.class))
.andReturn(employees);
This is a small quirk when using EasyMock 2.2...
18 comments:
Thanks Alex. That was precisely the issue I was facing today. Is a shame these quirks are not listed as part of the EasyMock documentation.
Thanks Matt. I'm glad that this post helped.
This tip was really useful. Thanks.
hi I am facing some similar kind of Exception, but in my case there is only parameter for the mocked method
expect(someMock.someMethod(isA(SomeObject.class))).andStubAnswer(same(new IAnswer<List<SomeReturnObject>>() {
public List<SomeReturnObject> answer() throws Throwable {
Object args[] = getCurrentArguments();
SomeObject ca = (SomeObject)args[0];
return new ArrayList<SomeReturnObject>(ca.getSomeReturnObjects());
}
}));
java.lang.IllegalStateException: 1 matchers expected, 2 recorded.
at org.easymock.internal.ExpectedInvocation.createMissingMatchers(ExpectedInvocation.java:41)
any ideas?
hi, I removed same method call
expect(someMock.someMethod(isA(SomeObject.class))).andStubAnswer(new IAnswer<List<SomeReturnObject>>() {
public List<SomeReturnObject> answer() throws Throwable {
Object args[] = getCurrentArguments();
SomeObject ca = (SomeObject)args[0];
return new ArrayList<SomeReturnObject>(ca.getSomeReturnObjects());
}
});
java.lang.IllegalStateException: 1 matchers expected, 2 recorded.
Hi anon, unfortunately I have never encountered the situation where the number of recorded matchers is greater than that of expected matchers. Without more code from your test case and the class under test, it is virtually impossible to figure out the cause of this problem...
Thanks so much for making this information available -- it helped me to quickly get past a problem which had me really stumped, and I can only guess how many hours it would have taken me to figure this out on my own. Kudos!
Excellent. What a strange quirk. Thank you.
Great man,
you solved my problems!!!
Thanks,
V.
Thanks Alex.
I had the same problem and spend quite some time before I found your blog.
Let me give you a even stranger quirk:
Suppose you want to expect a call with two params, where you must use isA, but the other parameter is null.
Suppose the signature looks like this:
methodName(MyOtherObject moo, MyObject mo);
Then the mock should look like this:
mock.methodName(null, isA(MyObject.class));
But that isn't supported as if you use a matcher, all arguments must use matcher. Ah, then this should work:
mock.methodName(isNull(), isA(MyObject.class));
But no, this doesn't compile unless the signature of methodName use Object as first parameter, which it seldom does.
So, heres the extremely ugly workaraound I found:
mock.methodName(not(isA(MyOtherObject.class)), isA(MyObject.class));
If someone has a neater solution, I'd be thrilled.
Hi Tomas,
Thanks for sharing your experience and your solution!
Alex
Tomas, try
mock.methodName((MyOtherObject)isNull(), isA(MyObject.class));
All,
I also have the same problem as the poster that has more recorded matchers than expected. the method i'm mocking has no arguments and returns a boolean, but if i debug the EasyMock code two instanceOf(Long.class) matchers have been recorded! I think this is a threading issue.
After so long, your solution is still helping! Thanks very much!!!
Thanks! Just ran into this issue.
i have a similar unsolved problem.
my mock statement is :
EasyMock.expect(slotManager.addSlotPageletBinding(EasyMock.isA(String.class), EasyMock.isA(String.class), EasyMock.isA(helloWorld.class))).andReturn(true);
this causes:
3 matchers expected, 4 recorded.
Not able find the problem.
before this statement i have the mock for the overloaded method as:
EasyMock.expect(slotManager.addSlotPageletBinding(EasyMock.isA(String.class),EasyMock.isA(String.class))).andReturn(true).anyTimes();
This has to do with using an argument matcher outside of EasyMock context
http://jira.codehaus.org/browse/EASYMOCK-38
Post a Comment