EasyMock and varargs

8:57 AM , 2 Comments

EasyMock is a neat tool for creating mocks at runtime for unit tests. It does some pretty cool things, including writing their main API using Fluent Pattern.

For example, when adding behavior to your mocks, you would call the following:


EasyMock.expect(...).andReturn(...).times(3).andReturn(...).times(2)...


Awesome.

There is one feature, though, that is lacking that can send you for a loop if you are unaware, which is varags.

If you need to add a behavior to a method that takes var args, you will need to how many parameters are going in at test time.

For example, say I have the following method:


Object myMethod(Object... args)


That I want to supply behavior for. In EasyMock, there isn't a way to say "this is a var args method". So, you will need to expand it according to your test case:


EasyMock.expect(myMethod(arg0, arg1, arg2)).andReturn(...)...


The reason is that EasyMock's strategy for method matching is to count the number of arguments in your behavior with the number of arguments in the method invocation. If you just say


EasyMock.expect((String[])EasyMock.anyObject())...


or something like that, it will see that there is only one parameter, whereas the method invocation parameters will never match.

Josh Cummings

"I love to teach, as a painter loves to paint, as a singer loves to sing, as a musician loves to play" - William Lyon Phelps

2 comments:

  1. Just what I was looking for, this was killing me trying to figure out why I was not getting a matcher with (String[])anyObject.

    ReplyDelete
  2. You can also use reflection, if the number of arguments is very big:

    Method myMethod = MyClass.class.getMethod("myMethod", String[].class);
    myMethod.invoke(myObject, new Object[] { generateLotsOfArguments() });
    expectLastCall().andReturn(...)...

    ReplyDelete