expect(mockObject.retrieveSomething((String) anyObject(), false)).andReturn(someObject);
Unfortunately, EasyMock and mockito do not like this. They both want you to use matchers for all parameters if you use matchers for any parameters. However, the two libraries react quite differently when this situation occurs. EasyMock complains with a somewhat confusing message that at first blush makes it seem like we declared the expectation for multiple invocations. It really threw us off for a while (at least an hour) trying to figure out what was wrong with our expectations. Here is how we fixed it in EasyMock:
expect(mockObject.retrieveSomething((String) anyObject(), eq(false))).andReturn(someObject);
Mockito does a much better job of stating that when you use a parameter argument matcher in your expectation, you have to use parameter argument matchers for all of the parameters of the method call participating in the expectation. I find it interesting that mockito retains the behavior of EasyMock (mockito is a fork of EasyMock) with regards to argument matching, but mockito improves on the error messaging when something goes wrong with the mock object setup. Further reinforces my decision to forego EasyMock in favor of mockito.
and what about Groovy testing?? :)
ReplyDeleteMockFor mockObject = new MockFor(ObjectBeingMocked)
def numberOfTimes = 1
mockObject.demand.retrieveSomething(numberOfTimes) { param1, param2 ->
assertFalse param2
return someObject
}
serviceUnderTest.object = mockObject.proxyDelegateInstance()
serviceUnderTest.doSomething()
mockObject.verify serviceUnderTest.object
Mike,
ReplyDeleteI'd love to introduce Groovy testing, but there's no one there that can take on the role of Groovy champion and guru. Not much more I can reveal. Thanks for the thoughts. I would definitely push for using Groovy for testing if I were to have a voice on a project that was looking to use testing to drive design.
-- chris --
Hi, I'm working on EasyMock. Both frameworks are behaving like this because it's impossible technically to do otherwise. Even I get misled once in a while. The thing is that if some matchers are missing, you can't guess on which parameters they should be. You just have a list of matchers and a list of parameters.
ReplyDeleteThen, it's interesting to know that Mockito gives a better error message. I'll need to check because I know there was a good (technical) reason for EasyMock to behave like it does.
Henri,
ReplyDeleteThanks for your note. Interestingly, I just had the same issue hit me in mockito (you'd think I'd learn after so many times of hitting this). Here's the stack trace you get from mockito when you don't use the argument matchers consistently in your expectation:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
3 matchers expected, 1 recorded.
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
Mockito makes it quite obvious what your issue is.
-- chris --
Amazing blog post,Thank you.
ReplyDeletelook here
Best Sofa Repair Services in Mico Layout