从本地内部类模拟访问外部对象

时间:2019-04-11 08:43:50

标签: java unit-testing junit mockito

我的一个方法中有一个带有本地内部类的类:

public class Outer {
    String hello = "hello";

    public void myMethod() {

        class Inner {
            public void myInnerMethod() {
                System.out.println(hello);         
            }
        }

        [...really slow routine...]

        (new Inner()).myInnerMethod();
    }
}

我想测试myInnerMethod()。因此,我使用反射实例化了本地内部类,并在其上调用了myInnerMethod()

public void test() {
    Object inner = Class.forName("Outer$Inner").newInstance();
    inner.getClass().getDeclaredMethod("myInnerMethod").invoke(inner); // hello will be null
}

但是,当myInnerMethod()访问hello(属于Outer类的范围)时,它就是null

是否可以模拟或向myInnerMethod()提供问候?

我知道我可以通过提取内部类或仅测试Outer的公共方法来重构代码。但是还有办法吗?

1 个答案:

答案 0 :(得分:1)

在验证内部行为之前,您需要进行一些小的重构:

1):创建一个包级方法,其中应包含从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)监视Outer类,并验证hello实例变量已调用printHello

public void test() {
    // Arrange
    Outer outerSpy = spy(new Outer());
    doNothing().when(outerSpy).printHello(anyString()); // optional

    // Act
    outer.myMethod();

    // Assert
    verify(outerSpy).printHello("hello");
}