如何在java中测试本地内部类方法?

Fil*_*sso 21 java junit unit-testing inner-classes

在许多应用程序中,我经常使用算法来利用专用的子算法(或简单明确定义的代码片段).

直到现在,当我编写主算法时,我为每个子算法创建了一个私有方法,如下例所示(OldStyle):

public class OldStyle {

    public int mainAlg() {
        int x = subAlg01();
        int y = subAlg02();
        int z = x * y;
        return z;
    }

    private int subAlg01() {
        return 3;
    }

    private int subAlg02() {
        return 5;
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好但我不喜欢增加方法(subAlg01和subAlg02),即使是私有的,也只使用一种方法(mainAlg).

最近我发现使用了本地内部类,现在我的例子是(NewStyle):

public class NewStyle {

    public int mainAlg() {
        class Nested {

            public int subAlg01() {
                return 3;
            }

            public int subAlg02() {
                return 5;
            }
        }
        Nested n = new Nested();
        int x = n.subAlg01();
        int y = n.subAlg02();
        int z = x * y;
        return z;
    }
}
Run Code Online (Sandbox Code Playgroud)

我非常喜欢它,但现在我遇到了以下问题:如何使用JUnit测试subAlg01和subAlg02?

顺便说一下:我正在使用eclipse.

谢谢你的帮助.

编辑:我试着更好地解释:我有一个排序算法,我想测试它,以确保它按预期运行.这种排序算法只用于类X的方法m.我可以使它成为类X的私有方法,但是类X通常与排序无关,那么为什么要用排序方法"破坏"类X呢?所以我把它放在方法m里面.一段时间后,我想改进我的排序算法(我让它更快)但我想确保它的行为符合预期,所以我想用原始测试重新测试它.

这就是我想要做的,也许没有解决方案,我希望有人可以帮助我.

在回答选择后编辑.我选择Rodney的答案是因为他的解决方案是我采用的解决方案:一个独立的助手类帮助我(这是一个帮手!)清楚地看到了什么是子方法,它也让我有能力测试它们.

Pét*_*rök 18

您应该只测试类的公共接口,而不是私有成员或私有内部类.私有成员应该是实现细节,仅由类的公共方法(直接或间接)使用.因此,您可以通过其调用方法间接地对这些进行单元测试.如果您觉得在这些单元测试中没有足够的粒度,或者您无法感知(某些)您感兴趣的结果,这可能会对您的设计造成问题:课程可能太大,尝试要做太多,因此可能需要将其某些功能提取到一个单独的类中,然后可以直接对其进行单元测试.

在当前示例中,如果内部类本身包含大量代码,您可以简单地将其转换为顶级类,然后您可以直接对其方法进行单元测试.

(顺便说一下,static如果不需要引用封闭的类实例,你的内部类应该是.)


Rod*_*zel 12

菲利波,我理解你对问题的沮丧和一些答案.当我多年前第一次开始使用JUnit时,我也想测试私有代码,我认为大师们说这是个坏主意是愚蠢的.

事实证明他们是对的(惊喜!),但只有在写了相当多的测试之后才明白为什么.您可能需要经历相同的过程,但最终会得出相同的结论;-)

无论如何,在你的情况下,我会Nested进入一个合适的独立类,可能在一个单独的包中,以明显它是一个帮助类.然后我会直接为它编写测试,独立于任何其他测试.

然后我会编写测试,NewStyle并只关注它的行为NewStyle.

(大抵相当我也注入NestedNewStyle而非内将其实例化NewStyle-即使它成为一个参数NewStyle的构造函数.

然后,当我NewStyle在测试中编写测试时,我会传入一个实例Nested并继续.如果我觉得特别棘手,我会创建一个接口Nested并创建第二个实现,并NewStyle使用它进行测试.)