Mock Access to Outer Object From Local Inner Class

Twilite :

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?

Maciej Kowalski :

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");
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=105260&siteId=1
Recommended