I have a factory method that creates objects to be used in unit tests. These objects all derive from the same base class:
public static <T extends BaseEntity> T modMake(Class<T> clazz)
{
try {
return clazz.newInstance();
} catch (InstantiationException e) {
// Should never happen
throw new AssertionError(e);
} catch (IllegalAccessException e) {
// Should never happen
throw new AssertionError(e);
}
}
Now I want to override a getter method from that base class, but just for the tests. I would usually do that with an anonymous class, for example (Node
being one of the subtaypes of BaseEntity
):
public static Node nodMake()
{
return new Node() {
@Override
public long ixGet() { return 1; }
};
}
Can I do that in the function using the Class
argument, too?
Lose your factory method and use a mocking API like EasyMock to achieve the behavior you describe.
Your code will then end up something like this:
long returnValue = 12;
Node nodeMock = createMock(Node.class);
expect(nodeMock.ixGet()).andReturn(returnValue);
replay(nodeMock);
//add test code here
verify(nodeMock);
To answer Hanno's question on how this works:
It depends on whether your mocking an interface or a class.
The case of the interface is simple (code-wise), it uses what's called a dynamic proxy, which is part of core Java.
In the case of the class it's doing the bytecode manipulation that @Jonathan mentions in his answer, just behind a nice API.
Both the above mechanisms allow the method calls to be intercepted and EasyMock simply responds based on the expectations you've setup.
I don't think there is any way to do that. You probably need to look into bytecode manipulators if you really need to go that route. Javassist and BCEL are a couple of choices.