首页 > 解决方案 > 从本地内部类模拟访问外部对象

问题描述

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

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 的公共方法。但是还有办法吗?

标签: javaunit-testingjunitmockito

解决方案


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

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类并验证printHello已使用 hello 实例变量调用:

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

    // Act
    outer.myMethod();

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

推荐阅读