VIP: The Right Way to do the Wrong Thing

PORTUGUÊS
SourceForge.net Logo

Introduction
How Does It Work?
Fake Accessors
Example
Download
Contact

Introduction

If you write unit tests in your java projects, then you had this problem before: testing private members. There are four solutions for testing private methods:


I wrote VIP because I prefer using reflection in my test cases, but I don't like all that reflection code hanging around. So I came with a very small and simple utility that will do the reflection rubbish for you.

VIP stands for Very Important Proxy ;-)

How Does It Work?

VIP creates a dynamic proxy that implements an interface defined by you. No xml configuration needed; the interface should have all info needed by VIP. If you want to test a private method, then add the same method signature to the interface (except for modifiers like private, static, etc). VIP returns you a dynamic proxy that implements that interface, so you may invoke the method as if it was public. VIP holds an instance of the target class (class under test) and forwards the method invocation, matching the method signatures and doing all the reflection rubbish for you.

Fake Accessors

Beside invoking private methods, you may also checkout private fields. If the target class does not provide public accessors, VIP offers you fake accessors. All you have to do is to declare the accessors in your custom interface, following java naming conventions. When you invoke a fake accessor VIP figures out that there is no matching method in the target class and tries to find a matching field for the accessor name.

Example

Suppose you want to test the following target class:

public class Foo {
	private int unreachable = 10;

private String sayBar() {
return "Bar!";
}

public Foo() {
}
}

Step 1: Define a custom interface, declaring as public all the private members you want to access. This should go together with all the testing code that will not be deployed with your application. I advise to include it in the same file of your test case.

interface IFoo {
int getUnreachable();
void setUnreachable(int unreachable);
String sayBar();
}

Step 2: Ask VIP for a proxy in your unit test.

public void testFoo() throws Exception {
...
IFoo proxy = (IFoo) VIPMaker.makeProxyForInstance(new Foo(), IFoo.class);

proxy.setUnreachable(20);
assertEquals(20, proxy.getUnreachable());
assertEquals("Bar!", proxy.sayBar());
...
}

That's all. You may also call VIPMaker.makeProxyForClass(Class, Class), in case you want VIP to instantiate the target class for you, trying all possible constructors.

Contact

Bernardo O. Bennett is a java consultant, currently working with Sakonnet Technology LLC. If you have questions or suggestions send me an e-mail.