EasyMock Arguments
Posted by Mike Haller
on Sunday, March 4. 2007
at 08:26
in Java
EasyMock ArgumentsTo mock objects, you need to know which methods are called with what parameters, so you can assert them.
For simple parameters like Strings or numbers, this is easy and you can record the value just by simply calling
the method:
IMyMock mock = myControl.createMock(IMyMock.class);
mock.doSomething("Foo"); // Point of interest
mock.replay();
// This will call IMyMock.doSomething("Bar")
// public void methodUnderTest() { myMock.doSomething("Bar"); }
classUnderTest.methodUnderTest();
// This will compare "Foo" with "Bar" and fail the test
mock.verify();
Here, mock.doSomething("Foo") will 1) record the method invocation of doSomething and 2) record the value "Foo"
for the first and only parameter.
For more complex parameter objects, or if you want to ease restrictions, you will probably want
to implement your own EasyMock IArgumentMatcher. In this case, the actual parameter within the unit test
source code does not matter and you can use null for them...
IMyMock mock = myControl.createMock(IMyMock.class);
EasyMock.reportMatcher(new MyOrMatcher("Foo","Bar","Baz"));
mock.doSomething(null); // Point of interest
mock.replay();
// This will call IMyMock.doSomething("Bar")
// public void methodUnderTest() { myMock.doSomething("Bar"); }
classUnderTest.methodUnderTest();
// This will compare "Foo" with "Bar" and fail the test
mock.verify();
The number of parameters and the number of registered matchers must be equal. There are some simple predefined
argument matchers like Any, NotNull, Equals etc.
It is also a good idea to create some Matchers which e.g. compare your value objects using reflection or some
Matcher for checking the contents of Collections. Sad that EasyMock does not contain richer Matchers.
Also, it can get quite annoying to compare method invocations like the following, as this leads to an Assert Error
description in the JUnit View which is ... rather long and not clearly arranged. It can take some time to even identify
which of the parameters actually failed the test.
Just compare the simple message with the more complex one:
java.lang.AssertionError:
Unexpected method call getNextDocNumber("FAPO", "EOP", "FOO", false, 2):
getNextDocNumber("OPAF", "EOP", "FOO", false, 2): expected: 1, actual: 0
java.lang.AssertionError:
Unexpected method call store([com.foo.vo.SomeValueObjectData@b8bef7[
set_id=null
timecreated=null
createdby=null
timemodified=null
modifiedby=null
execution=null
ourParty=null
counterParty=null
executionStatus=null
pricedUnpricedDeb=null
totalInventoryValue=null
executionPrice=null
bookedPrice=null
siteId=null
purchaseSaleIndicator=null
ctrNo=null
executionNumber=null
accountId=null
partySubtype=null
accrualProce=null
marketPriceEndOfMonth=null
effectiveDate=null
contractYear=null
showExecutionPrice=null
contractNumber=null
commodityNumber=null
accrualValue=null
totalInventoryQuantity=null
totalAllocatedQuantity=null
fintransSubtype=null
marketId=null
premiumDiscount=null
pricedQuantity=null
pricedUSD=null
netAmount=null
netForeignAmount=null
quotationalPeriodStart=null
quotationalPeriodEnd=null
pricingNumber=null
executionId=null
premiumDiscountPercentage=null
premiumDiscountFXRate=null
partType=null
]], "junit", 1):
store([com.foo.vo.SomeValueObjectData@b7bgf3[
set_id=null
timecreated=null
createdby=null
timemodified=null
modifiedby=null
execution=null
ourParty=null
counterParty=null
executionStatus=null
pricedUnpricedDeb=null
totalInventoryValue=null
executionPrice=null
bookedPrice=null
siteId=null
purchaseSaleIndicator=null
ctrNo=null
executionNumber=null
accountId=null
partySubtype=null
accrualProce=null
marketPriceEndOfMonth=null
effectiveDate=null
contractYear=null
showExecutionPrice=null
contractNumber=null
commodityNumber=null
accrualValue=null
totalInventoryQuantity=null
totalAllocatedQuantity=null
fintransSubtype=null
marketId=Test
premiumDiscount=null
pricedQuantity=null
pricedUSD=null
netAmount=null
netForeignAmount=null
quotationalPeriodStart=null
quotationalPeriodEnd=null
pricingNumber=null
executionId=null
premiumDiscountPercentage=null
premiumDiscountFXRate=null
partType=null
]], "junit", 1): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler
.invoke(MockInvocationHandler.java:29)
at org.easymock.internal.ObjectMethodsFilter
.invoke(ObjectMethodsFilter.java:45)
at $Proxy3.store(Unknown Source)
Did you find the difference? Never mind, with a little trick and a custom Matcher, you can get a
more helpful message:
java.lang.AssertionError:
Unexpected method call execute(...):
execute(
pv_execstatus1: Expected 'O' but was 'F'
pv_execstatus2: Expected 'F' but was 'O'
): expected: 1, actual: 0
store(, "junit", 1): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler
.invoke(MockInvocationHandler.java:29)
at org.easymock.internal.ObjectMethodsFilter
.invoke(ObjectMethodsFilter.java:45)
at $Proxy3.execute(Unknown Source)
Happy mocking
