views:

48

answers:

1

Suppose I have an interface with lots of methods that I want to mock for a test, and suppose that I don't need it to do anything, I just need the object under test to have an instance of it. For example, I want to run some performance testing/benchmarking over a certain bit of code and don't want the methods on this interface to contribute.

There are plenty of tools to do that easily, for example

Interface mock = Mockito.mock(Interface.class);
ObjectUnderTest obj = ...
obj.setItem(mock);

or whatever.

However, they all come with some runtime overhead that I would rather avoid:

  • Mockito records all calls, stashing the arguments for verification later
  • JMock and others (I believe) require you to define what they going to do (not such a big deal), and then execution goes through a proxy of various sorts to actual invoke the method.
  • Good old java.lang.reflect.Proxy and friends all go through at least a few more method calls on the stack before getting to the method to be invoked, often reflectively.

(I'm willing to be corrected on any of the details of those examples, but I believe the principle holds.)

What I'm aiming for is a "real" no-op implementation of the interface, such as I could write by hand with everything returning null, false or 0. But that doesn't help if I'm feeling lazy and the interface has loads of methods. So, how can I generate and instantiate such a no-op implementation of an arbitrary interface at runtime?

There are tools available such as Powermock, CGLib that use bytecode generation, but only as part of the larger mocking/proxying context and I haven't yet figured out what to pick out of the internals.

OK, so the example may be a little contrived and I doubt that proxying will have too substantial an impact on the timings, but I'm curious now as to how to generate such a class. Is it easy in CGLib, ASM?


EDIT: Yes, this is premature optimisation and there's no real need to do it. After writing this question I think the last sentence didn't quite make my point that I'm more interested in how to do it in principle, and easy ways into dynamic class-generation than the actual use-case I gave. Perhaps poorly worded from the start.

+3  A: 

Not sure if this is what you're looking for, but the "new class" wizard in Eclipse lets you build a new class and specify superclass and/or interface(s). If you let it, it will auto-code up dummy implementations of all interface/abstract methods (returning null unless void). It's pretty painless to do.

I suspect the other "big name" IDEs, such as NetBeans and Idea, have similar facilities.


EDIT:

Looking at your question again, I wonder why you'd be concerned about performance of auto proxies when dealing with test classes. It seems to me that if performance is an issue, you should be testing "real" functionality, and if you're dealing with mostly-unimplemented classes anyway then you shouldn't be in a testing situation where performance matters.

Carl Smotricz
+1 for the edit
matt b
Agreed. This smells like premature optimisation, too - how many picoseconds are those couple of extra stack layers costing you with Java's dynamic proxies, anyway?
Andrzej Doyle
Yeah, I know. In honesty, the "how might one do it" part is more important than "I actually need to do it".
Joe Kearney
@Carl: Creating the new class is, admittedly probably the best solution for the motivating case I gave, fair enough. I'm interested more in figuring out how to do it dynamically, perhaps that wasn't clear.
Joe Kearney