I have a class with a local inner class in one of its methods:
public class Outer {
String hello = "hello";
public void myMethod() {
class Inner {
public void myInnerMethod() {
System.out.println(hello);
}
}
[...really slow routine...]
(new Inner()).myInnerMethod();
}
}
I would like to test the myInnerMethod()
. So I instantiate the local inner class using reflection and call the myInnerMethod()
on it.
public void test() {
Object inner = Class.forName("Outer$Inner").newInstance();
inner.getClass().getDeclaredMethod("myInnerMethod").invoke(inner); // hello will be null
}
But when myInnerMethod()
accesses hello
, which is in the scope of the Outer class, it is null
.
Is there a way to mock or otherwise provide hello to myInnerMethod()
?
I know I could refactor my code by extracting the inner class or just test the public methods of Outer. But is there still a way to do it?
You would need to make some small refactoring before being able to verify the inner behavior:
1) Create a package level method that would contain the code invoked from within the myInnerMEthod
:
public class Outer {
String hello = "hello";
public void myMethod() {
class Inner {
public void myInnerMethod() {
Outer.this.printHello(hello); // !!! change here
}
}
[...really slow routine...]
(new Inner()).myInnerMethod();
}
void printHello(String hello){/* */} // !! add this
}
2) Spy on the Outer
class and verify the printHello
has been called with the hello instance variable:
public void test() {
// Arrange
Outer outerSpy = spy(new Outer());
doNothing().when(outerSpy).printHello(anyString()); // optional
// Act
outer.myMethod();
// Assert
verify(outerSpy).printHello("hello");
}