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

2022-09-01 20:41:21

在许多应用程序中,我经常使用专用子算法(或简单地定义良好的代码段)的算法。

到目前为止,当我编写主算法时,我为每个子算法创建了一个私有方法,如下面的示例(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;
    }
}

这工作得很好,但我不喜欢有大量的方法(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;
    }
}

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

顺便说一句:我正在使用eclipse。

感谢您的帮助。

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

这就是我想做的,也许没有解决方案,我希望有人能帮助我。

在答案选择后进行编辑。我之所以选择Rodney answer,是因为他的解决方案是我采用的:一个独立的帮助器类可以帮助我(它是一个帮助器!)清楚地了解什么是子方法,它还让我能够测试它们。


答案 1

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

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

(顺便说一句,如果内部类不需要引用封闭类实例,则它应该是静态的。


答案 2

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

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

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

然后我会为 编写测试,只关注 的行为。NewStyleNewStyle

(很可能我也会注入而不是在里面实例化它 - 即让它成为构造函数的参数。NestedNewStyleNewStyleNewStyle

然后,当我在测试中编写测试时,我会通过一个实例并继续。如果我觉得特别棘手,我会创建一个接口并创建第二个实现,并用它来进行测试。NewStyleNestedNestedNewStyle


推荐