Joe Kearney
Joe Kearney

Reputation: 7547

cheap way to mock an interface with no runtime overhead

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:

(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.

Upvotes: 1

Views: 905

Answers (2)

Kevin Welker
Kevin Welker

Reputation: 7947

It would take a little work to build the utility, but probably not too hard for basic vanilla Java interface without "edge cases" (annotations, etc), to use Javassist code generation to textually create a class at runtime that implements null versions of every method defined on the interface. This would be different from Javassist ProxyFactory (Or CGLib Enhancer) proxy objects which would still have a few layers of indirection. I think there would be no overhead in the resulting class from the direct bytecode generation mode. If you are brave you could also dive into ASM to do the same thing.

Upvotes: 0

Carl Smotricz
Carl Smotricz

Reputation: 67820

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.

Upvotes: 3

Related Questions