【问题标题】:How do I test a class that has private methods, fields or inner classes?如何测试具有私有方法、字段或内部类的类?
【发布时间】:2011-09-26 10:53:16
【问题描述】:

如何使用 JUnit 测试具有内部私有方法、字段或嵌套类的类?

为了能够运行测试而更改方法的访问修饰符似乎很糟糕。

【问题讨论】:

  • 测试私有方法的最佳方法不是直接测试它
  • 为什么要测试私有函数?当您测试使用它的私有功能的功能/方法时,无论如何它都会自动测试(并且必须测试)。
  • 在生成问题之前,我已将此问题恢复为原始状态。在目前的状态下,答案是高度面向 Java 的,问题主要集中在“如何”上,这意味着后来的版本删除了 Java 并泛化为其他语言,最后将焦点转移到 C++ 上也失效了很多答案。用任意语言和框架询问“如何”的通用形式也将被认为过于宽泛,这意味着最后几次编辑将这个问题推向了封闭而不是建设性的问题。

标签: java unit-testing junit tdd


【解决方案1】:

测试私有方法的最佳方法是通过另一个公共方法。如果无法做到这一点,则以下条件之一为真:

  1. 私有方法是死代码
  2. 您正在测试的类附近有一种设计气味
  3. 您尝试测试的方法不应是私有的

【讨论】:

  • 此外,无论如何,我们永远不会接近 100% 的代码覆盖率,所以为什么不将您的时间集中在客户实际直接使用的方法上进行质量测试。
  • @grinch 现货。测试私有方法唯一能得到的就是调试信息,这就是调试器的用途。如果您对班级合同的测试完全覆盖,那么您就拥有了所需的所有信息。私有方法是一个实现细节。如果您对它们进行测试,您将不得不在每次实现更改时更改您的测试,即使合同没有更改。在软件的整个生命周期中,这可能会比它带来的收益高出很多。
  • 我印象深刻的是“不应该是私人的”声明在这里的答案中重复出现的频率,好像“将其公开以便您可以测试它”不容易导致代码异味其他人滥用课程的一部分。仅仅为了更轻松地测试各种代码路径而公开合理的内部结构并不总是明智的,所以不要在这里盲目地遵循这个设备!
  • 这里的“不应该是私有的”并不是说“只是为了测试而公开”。如果需要对私有方法进行测试,那肯定有他这里提到的三个条件。如果您想要 100% 的测试覆盖率,仍然可以通过使用各种参数调用类的公共方法来实现,除非它未使用或包含死代码,例如。 if (x == null) 永远无法到达,因为您已经在公共方法中进行了空检查。但是你应该清理私有方法,而不是发明不可能发生的测试用例。
  • 一个反例(真实)情况,这三点都不有效(据我所知):公共方法 foo() 将 1. 使用私有方法 bar() 和 2。无限循环运行。据我所知,您不能通过调用 foo() 来测试 bar() ,否则测试用例将永远运行。
【解决方案2】:

通常,单元测试旨在测试类或单元的公共接口。因此,私有方法是您不希望显式测试的实现细节。

【讨论】:

  • 这是 IMO 的最佳答案,或者通常所说的测试行为,而不是方法。单元测试不能替代源代码指标、静态代码分析工具和代码审查。如果私有方法非常复杂以至于它们需要单独的测试,那么它可能需要重构,而不是更多的测试。
  • 所以不要写私有方法,只创建10个其他小类?
  • 不,这基本上意味着您可以使用调用它们的公共方法来测试私有方法的功能。
  • @AkshatSharda 正确 - 而且,如果您无法通过公共 API 测试私有方法的某些部分,那么您可能不需要私有方法中的该功能。我发现“通过 API 进行测试”方法的副作用是您编写的死代码更少。
  • 我不同意。如果我想确定我的代码,我想测试代码流经过的每一部分。 Unit 甚至可以是实现自包含逻辑的私有方法。
【解决方案3】:

私有方法由公共方法调用,因此公共方法的输入还应测试由这些公共方法调用的私有方法。当公共方法失败时,可能是私有方法失败。

【讨论】:

  • 真实的事实。问题是当实现更复杂时,例如一个公共方法调用多个私有方法。哪一个失败了?或者如果它是一个复杂的私有方法,它不能被暴露也不能转移到一个新的类中
  • 您已经提到了为什么要测试私有方法。您说“那可能是”,所以您不确定。 IMO,是否应测试方法与其访问级别正交。
【解决方案4】:

来自这篇文章:Testing Private Methods with JUnit and SuiteRunner(Bill Venners),你基本上有4个选择:

  1. 不要测试私有方法。
  2. 授予方法包访问权限。
  3. 使用嵌套测试类。
  4. 使用反射。

【讨论】:

  • @JimmyT.,取决于“生产代码”的用途。我会将为驻留在 VPN 中且目标用户是系统管理员的应用程序生成的代码称为生产代码。
  • @Pacerier 你是什么意思?
  • 第五个选项,就像上面所说的测试调用私有方法的公共方法?对吗?
  • @LorenzoLerate 我一直在努力解决这个问题,因为我正在做嵌入式开发,我希望我的软件尽可能小。尺寸限制和性能是我能想到的唯一原因。
  • @user2441441 与 #1 相同——不要测试私有方法
【解决方案5】:

我倾向于不测试私有方法。那里有疯狂。就个人而言,我认为你应该只测试你公开的接口(包括受保护的和内部的方法)。

【讨论】:

    【解决方案6】:

    对于 Java,我会使用 reflection,因为我不喜欢仅仅为了测试而更改对声明方法的包的访问权限的想法。但是,我通常只测试公共方法,这也应该确保私有方法正常工作。

    您不能使用反射从所有者类外部获取私有方法,私有修饰符也会影响反射

    这不是真的。正如Cem Catikkas's answer 中提到的,您当然可以。

    【讨论】:

    • 你不能使用反射从所有者类之外获取私有方法,私有修饰符也会影响反射Here关于问题主题的一篇好文章
    • @jmfsg 您链接到链接的文章专门说“测试私有方法涉及更多一些;但我们仍然可以使用System.Reflection 来完成它。” (显然你需要ReflectionPermission,但这通常不是问题。)
    【解决方案7】:

    更新:

    大约 10 年后,测试私有方法或任何无法访问的成员的最佳方法可能是通过 Manifold 框架中的 @Jailbreak

    @Jailbreak Foo foo = new Foo();
    // Direct, *type-safe* access to *all* foo's members
    foo.privateMethod(x, y, z);
    foo.privateField = value;
    

    这样您的代码就可以保持类型安全和可读性。没有设计妥协,没有为了测试而过度曝光的方法和领域。

    如果您有一些遗留的 Java 应用程序,并且不允许更改方法的可见性,那么测试私有方法的最佳方法是使用 reflection

    在内部,我们使用助手来获取/设置 privateprivate static 变量以及调用 privateprivate static 方法。以下模式将让您做几乎所有与私有方法和字段相关的事情。当然,你不能通过反射改变private static final变量。

    Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
    method.setAccessible(true);
    return method.invoke(targetObject, argObjects);
    

    对于字段:

    Field field = TargetClass.getDeclaredField(fieldName);
    field.setAccessible(true);
    field.set(object, value);
    

    注意事项:
    1. TargetClass.getDeclaredMethod(methodName, argClasses) 让您查看private 方法。同样的事情适用于 getDeclaredField.
    2.setAccessible(true)是用来玩私服的。

    【讨论】:

    • 如果您可能不了解 API,这很有用,但如果您必须以这种方式测试私有方法,那么您的设计就有问题了。正如另一张海报所说,单元测试应该测试类的契约:如果契约太宽泛并且实例化了太多的系统,那么应该解决设计问题。
    • 我们开发了执行单个特定任务的方法,允许类执行其特定任务。这些方法不应该公开,仍然需要独立测试。所以是的,反射是一个很好的方法,如果你为此目的使用反射,你的设计不需要审查。
    【解决方案8】:

    在尝试过 Cem Catikkas 的 solution using reflection 用于 Java 之后,我不得不说他的解决方案比我在这里描述的更优雅。但是,如果您正在寻找使用反射的替代方法,并且可以访问您正在测试的源,这仍然是一个选择。

    测试类的私有方法可能有好处,尤其是test-driven development,您希望在编写任何代码之前设计小型测试。

    创建一个可以访问私有成员和方法的测试可以测试难以专门针对仅访问公共方法的代码区域。如果公共方法涉及多个步骤,则它可以包含多个私有方法,然后可以单独测试。

    优点:

    • 可以测试到更精细的粒度

    缺点:

    • 测试代码必须位于同一个 文件作为源代码,可以是 更难维护
    • 与 .class 输出文件类似,它们必须保留在与源代码中声明的相同的包中

    但是,如果连续测试需要这种方法,这可能是一个信号,应该提取私有方法,可以用传统的公共方式进行测试。

    这是一个令人费解的例子,说明它是如何工作的:

    // Import statements and package declarations
    
    public class ClassToTest
    {
        private int decrement(int toDecrement) {
            toDecrement--;
            return toDecrement;
        }
    
        // Constructor and the rest of the class
    
        public static class StaticInnerTest extends TestCase
        {
            public StaticInnerTest(){
                super();
            }
    
            public void testDecrement(){
                int number = 10;
                ClassToTest toTest= new ClassToTest();
                int decremented = toTest.decrement(number);
                assertEquals(9, decremented);
            }
    
            public static void main(String[] args) {
                junit.textui.TestRunner.run(StaticInnerTest.class);
            }
        }
    }
    

    内部类将被编译为ClassToTest$StaticInnerTest

    另请参阅:Java Tip 106: Static inner classes for fun and profit

    【讨论】:

      【解决方案9】:

      如果您尝试测试不愿意或无法更改的现有代码,反射是一个不错的选择。

      如果该类的设计仍然灵活,并且您有一个复杂的私有方法想要单独测试,我建议您将其拉到一个单独的类中并单独测试该类。这不必改变原始类的公共接口;它可以在内部创建助手类的实例并调用助手方法。

      如果您想测试来自辅助方法的困难错误条件,您可以更进一步。从帮助类中提取一个接口,在原类中添加一个公共的getter和setter来注入帮助类(通过其接口使用),然后将帮助类的mock版本注入到原类中,以测试原类如何响应助手的异常。如果您想测试原始类而不测试辅助类,这种方法也很有帮助。

      【讨论】:

        【解决方案10】:

        如果您想测试无法更改代码的遗留应用程序的私有方法,Java 的一个选项是jMockit,它允许您为对象创建模拟,即使它们是私有的类。

        【讨论】:

        • 作为 jmockit 库的一部分,您可以访问 Deencapsulation 类,这使得测试私有方法变得容易:Deencapsulation.invoke(instance, "privateMethod", param1, param2);
        • 我一直使用这种方法。很有帮助
        【解决方案11】:

        当我的类中有足够复杂的私有方法时,我觉得有必要直接测试私有方法,这就是代码异味:我的类太复杂了。

        我解决此类问题的常用方法是梳理出一个包含有趣部分的新类。通常,这个方法和与之交互的字段,也许还有另外一两个方法可以被提取到一个新的类中。

        新类将这些方法公开为“公共”,因此它们可用于单元测试。新旧类现在都比原来的类简单,这对我来说很棒(我需要保持简单,否则我会迷路!)。

        请注意,我并不是建议人们不使用大脑就创建课程!这里的重点是使用单元测试的力量来帮助您找到好的新类。

        【讨论】:

        • 既然可以公开您的方法,为什么还要创建一个新类?
        • 如果您在一个类中混合使用了私有和公共方法,这表明存在多种职责。
        • 在测试中使用反射访问私有方法。例如,我在私有方法中实现了一个算法,并且该方法在另一个公共方法中使用。所以我需要正确地测试这个算法(即使我正在编写这个算法)。那么,为什么我需要对生产代码进行破解才能测试这种方法呢?是的,使用 java 反射也是一种 hack,但仅限于测试中。如果我决定将方法(出于其他原因)移动到 utils 类中,我也可以移动测试......完成。简单易读、易读、可维护。
        【解决方案12】:

        正如上面许多人所建议的,一个好方法是通过您的公共接口测试它们。

        如果您这样做,最好使用代码覆盖工具(如 Emma)来查看您的私有方法是否实际上正在从您的测试中执行。

        【讨论】:

        • 你不应该间接测试!不仅通过覆盖触及;测试是否达到了预期的结果!
        【解决方案13】:

        如果您使用的是 JUnit,请查看 junit-addons。它具有忽略 Java 安全模型并访问私有方法和属性的能力。

        【讨论】:

          【解决方案14】:

          首先,我要抛出这个问题:为什么您的私人成员需要隔离测试?它们是否那么复杂,提供如此复杂的行为以至于需要在公共表面之外进行测试?这是单元测试,而不是“代码行”测试。不要为小事出汗。

          如果它们大到足以使这些私有成员在复杂性上都是一个“单元”——考虑将这些私有成员重构出这个类。

          如果重构不合适或不可行,是否可以在单元测试时使用策略模式来替换对这些私有成员函数/成员类的访问?在单元测试中,该策略将提供额外的验证,但在发布版本中,它将是简单的传递。

          【讨论】:

          • 因为通常来自公共方法的特定代码片段被重构为内部私有方法,并且确实是您可能出错的关键逻辑片段。您想独立于公共方法进行测试
          • 即使是最短的代码,有时没有单元测试也是不正确的。只需尝试计算 2 个地理角度之间的差异。 4行代码,第一次尝试大多数都不会正确。此类方法需要单元测试,因为它构成了可信赖代码的基础。 (Ans 这样有用的代码也可以是公开的;不太有用的保护
          【解决方案15】:

          测试私有方法会破坏类的封装,因为每次更改内部实现都会破坏客户端代码(在本例中是测试)。

          所以不要测试私有方法。

          【讨论】:

          • 单元测试和src代码是一对。如果你改变了src,也许你必须改变单元测试。这就是junit测试的意义。他们将保证一切正常。如果你改变代码,如果它们坏了也没关系。
          • 不同意如果代码更改,单元测试应该更改。如果您被命令在不更改类的现有功能的情况下向类添加功能,那么即使您更改了代码,现有的单元测试也应该通过。正如 Peter 所提到的,单元测试应该测试接口,而不是它是如何在内部完成的。在测试驱动开发中,单元测试是在编写代码之前创建的,专注于类的接口,而不是内部如何解决。
          【解决方案16】:

          正如其他人所说...不要直接测试私有方法。以下是一些想法:

          1. 保持所有方法小而专注(易于测试,易于发现问题)
          2. 使用代码覆盖工具。我喜欢Cobertura(哦,快乐的一天,好像有新版本了!)

          在单元测试中运行代码覆盖率。如果您发现方法未经过全面测试,请添加到测试中以提高覆盖率。以 100% 的代码覆盖率为目标,但要意识到您可能无法实现。

          【讨论】:

          • 提高代码覆盖率。无论私有方法中有什么样的逻辑,你仍然是通过公共方法调用这些逻辑。代码覆盖率工具可以显示测试覆盖了哪些部分,因此您可以查看您的私有方法是否经过测试。
          • 我见过唯一的公共方法是 main[] 的类,它们会弹出 GUI 并连接数据库和全球的几个 Web 服务器。容易说“不要间接测试”...
          【解决方案17】:

          您可以关闭反射的 Java 访问限制,这样私有就没有任何意义了。

          setAccessible(true) 调用就是这样做的。

          唯一的限制是 ClassLoader 可能不允许您这样做。

          请参阅 Subverting Java Access Protection for Unit Testing (Ross Burton),了解在 Java 中执行此操作的方法。

          【讨论】:

            【解决方案18】:

            在 C# 中您可以使用 System.Reflection,但在 Java 中我不知道。尽管无论如何我都想回答这个问题,因为如果您“觉得需要对私有方法进行单元测试”,我的猜测是还有其他问题……

            我会认真考虑重新审视我的建筑......

            【讨论】:

              【解决方案19】:

              如果您的测试类与应测试的类在同一个包中怎么办?

              但当然在不同的目录中,srcclasses 用于您的源代码,test/srctest/classes 用于您的测试类。并让 classestest/classes 在您的类路径中。

              【讨论】:

              • 测试可以在不同的文件夹中(如src/test/java和src/main/java中的应用代码),但包必须相同。
              【解决方案20】:

              我过去曾使用reflection 为 Java 执行此操作,在我看来这是一个很大的错误。

              严格来说,您应该编写直接测试私有方法的单元测试。您应该测试的是类与其他对象的公共契约;您永远不应该直接测试对象的内部结构。如果另一个开发人员想要对类进行小的内部更改,这不会影响类公共合同,那么他/她必须修改基于反射的测试以确保它有效。如果您在整个项目中反复执行此操作,那么单元测试将不再是衡量代码健康状况的有用指标,并开始成为开发的障碍,并让开发团队感到烦恼。

              我建议改为使用 Cobertura 等代码覆盖率工具,以确保您编写的单元测试在私有方法中提供良好的代码覆盖率。这样,您可以间接测试私有方法的作用,并保持更高水平的敏捷性。

              【讨论】:

              • 对此+1。在我看来,这是对这个问题的最佳答案。通过测试私有方法,您正在测试实现。这违背了单元测试的目的,即测试类合同的输入/输出。一个测试应该对实现有足够的了解以模拟它在其依赖项上调用的方法。而已。如果你不能在不改变测试的情况下改变你的实现——你的测试策略很可能很糟糕。
              • @Colin M 但这并不是他真正要问的 ;) 让他来决定,你不知道这个项目。
              • 不是真的。通过使用它的公共方法来测试一小部分私有方法可能需要付出很多努力。在到达调用私有方法的行之前,公共方法可能需要进行大量设置
              • 我同意。你应该测试,如果合同被履行。你不应该测试,这是如何完成的。如果在没有达到 100% 代码覆盖率(在私有方法中)的情况下完成了联系,那可能是死代码或无用代码。
              • 非平凡的私有方法是一种代码味道,表明需要将代码重构为适当的公共方法/服务。
              【解决方案21】:

              我想测试私有方法的两个例子:

              1. 解密例程 - 我不会 想让它们对任何人可见,只是为了 为了测试,否则任何人都可以 使用它们来解密。但他们是 代码固有的,复杂的, 并且需要始终工作(明显的例外是反射,在大多数情况下,当SecurityManager 未配置为防止这种情况时,它甚至可以用于查看私有方法)。
              2. 为社区创建 SDK 消费。在这里,公众采取了 完全不同的意思,因为这 是全世界都可以看到的代码 (不仅仅是我的应用程序内部)。我放 如果我不将代码写入私有方法 希望 SDK 用户看到它 - 我 不要将此视为代码气味,只是 SDK 编程的工作原理。但是的 当然我还需要测试我的 私有方法,它们在哪里 我的 SDK 的功能实际上 生活。

              我理解只测试“合同”的想法。但我不认为有人可以提倡实际上不测试代码 - 你的里程可能会有所不同。

              因此,我的权衡是将 JUnit 与反射复杂化,而不是损害我的安全性和 SDK。

              【讨论】:

              • 虽然你永远不应该公开一个方法来测试它,private 不是唯一的选择。没有访问修饰符是package private,这意味着只要您的单元测试存在于同一个包中,您就可以对其进行单元测试。
              • 我在评论您的回答,尤其是第 1 点,而不是 OP。没有必要仅仅因为您不希望它公开而将方法设为私有。
              • @ngreen true thx - 我对“公共”这个词很懒惰。我已经更新了答案以包括公共、受保护、默认(并提到反射)。我试图说明的一点是,某些代码有充分的理由保密,但这不应该阻止我们对其进行测试。
              • 感谢大家举出真实的例子。大多数答案都很好,但从理论上讲。在现实世界中,我们确实需要对合约隐藏实现,而且我们仍然需要对其进行测试。阅读所有这些,我认为这应该是一个全新的测试级别,使用不同的名称
              • 另一个例子 - Crawler HTML 解析器。必须将整个 html 页面解析为域对象需要大量的基本逻辑来验证结构的一小部分。将其分解为方法并从一个公共方法调用它是有意义的,但是将所有组成它的较小方法都公开是没有意义的,每个 HTML 页面创建 10 个类也没有多大意义。
              【解决方案22】:

              要测试带有大而古怪的类的遗留代码,能够测试我正在编写的一个私有(或公共)方法通常非常有帮助

              我使用 Java 的 junitx.util.PrivateAccessor-package。许多有用的单行代码可用于访问私有方法和私有字段。

              import junitx.util.PrivateAccessor;
              
              PrivateAccessor.setField(myObjectReference, "myCrucialButHardToReachPrivateField", myNewValue);
              PrivateAccessor.invoke(myObjectReference, "privateMethodName", java.lang.Class[] parameterTypes, java.lang.Object[] args);
              

              【讨论】:

              • 请务必下载整个 JUnit-addons (sourceforge.net/projects/junit-addons) 包,而不是 Source Forge 推荐项目 PrivateAccessor。
              • 并确保,当您在这些方法中使用 Class 作为您的第一个参数时,您只能访问 static 成员。
              【解决方案23】:

              JUnit.org FAQ page的回答:

              但如果你必须...

              如果你使用的是JDK 1.3或更高版本,可以使用反射来颠覆 借助PrivilegedAccessor 的访问控制机制。 有关如何使用它的详细信息,请阅读this article

              如果您使用的是 JDK 1.6 或更高版本并且您使用 @Test,您可以使用Dp4j 在您的测试方法中注入反射。为了 具体使用方法见this test script

              附:我是Dp4j 的主要贡献者,如果您需要帮助,请询问me。 :)

              【讨论】:

                【解决方案24】:

                我只测试公共接口,但众所周知我会保护特定的私有方法,因此我可以完全模拟它们,或者添加特定于单元测试目的的额外步骤。一般情况是挂接我可以从单元测试中设置的标志,以使某些方法故意导致异常能够测试故障路径;异常触发代码仅在受保护方法的覆盖实现中的测试路径中。

                不过,我尽量减少对此的需求,并且我总是记录确切的原因以避免混淆。

                【讨论】:

                  【解决方案25】:

                  我不确定这是否是一项好技术,但我开发了以下模式来对私有方法进行单元测试:

                  我不修改要测试的方法的可见性并添加其他方法。相反,我为我想要测试的每个私有方法添加了一个额外的公共方法。我将此附加方法称为Test-Port,并用前缀t_ 表示它们。这个Test-Port 方法然后简单地访问相应的私有方法。

                  此外,我在Test-Port 方法中添加了一个布尔标志,以决定是否从外部通过Test-Port 方法授予对私有方法的访问权限。然后在我放置的静态类中全局设置此标志,例如应用程序的其他全局设置。所以我可以在一个地方打开和关闭对私有方法的访问,例如在相应的单元测试中。

                  【讨论】:

                    【解决方案26】:

                    Groovy 有一个bug/feature,通过它您可以像调用公共方法一样调用私有方法。因此,如果您能够在项目中使用 Groovy,那么您可以使用它来代替反射。以this page 为例。

                    【讨论】:

                    • 这是一个hack,不是真正的解决方案。
                    • @givanse 我不同意...这是使用 Groovy 测试 Java 代码如此强大的原因之一。
                    【解决方案27】:

                    JML 有一个 spec_public 注释注释语法,允许您在测试期间将方法指定为公共:

                    private /*@ spec_public @*/ int methodName(){
                    ...
                    }
                    

                    http://www.eecs.ucf.edu/~leavens/JML/jmlrefman/jmlrefman_2.html#SEC12 讨论了此语法。还有一个将 JML 规范转换为 JUnit 测试的程序。我不确定它的效果如何或它的功能如何,但似乎没有必要,因为 JML 本身就是一个可行的测试框架。

                    【讨论】:

                      【解决方案28】:

                      今天,我推送了一个 Java 库来帮助测试私有方法和字段。它的设计考虑了 Android,但它确实可以用于任何 Java 项目。

                      如果您有一些带有私有方法或字段或构造函数的代码,您可以使用BoundBox。它完全符合您的要求。 下面是一个访问 Android Activity 的两个私有字段以对其进行测试的测试示例:

                      @UiThreadTest
                      public void testCompute() {
                      
                          // Given
                          boundBoxOfMainActivity = new BoundBoxOfMainActivity(getActivity());
                      
                          // When
                          boundBoxOfMainActivity.boundBox_getButtonMain().performClick();
                      
                          // Then
                          assertEquals("42", boundBoxOfMainActivity.boundBox_getTextViewMain().getText());
                      }
                      

                      BoundBox 可以轻松测试私有/受保护的字段、方法和构造函数。你甚至可以访问被继承隐藏的东西。事实上,BoundBox 打破了封装。它会让你通过反射访问所有这些,但是在编译时会检查所有内容。

                      它非常适合测试一些遗留代码。小心使用它。 ;)

                      https://github.com/stephanenicolas/boundbox

                      【讨论】:

                      • 刚试了一下,BoundBox是一个简单优雅的解决方案!
                      【解决方案29】:

                      私有方法被公共方法使用。否则,它们就是死代码。这就是为什么您要测试公共方法,断言公共方法的预期结果,从而断言它使用的私有方法。

                      在对公共方法运行单元测试之前,应通过调试来测试私有方法。

                      它们也可以使用测试驱动开发进行调试,调试单元测试直到满足所有断言。

                      我个人认为使用 TDD 创建类会更好;创建公共方法存根,然后使用 all 预先定义的断言生成单元测试,因此在编码之前确定方法的预期结果。这样,您就不会走上错误的道路,使单元测试断言适合结果。当您的所有单元测试都通过时,您的类就会变得健壮并满足要求。

                      【讨论】:

                      • 虽然这是事实,但它会导致一些非常复杂的测试——一次测试一个方法(单元测试)而不是一组方法是更好的模式。不是一个糟糕的建议,但我认为这里有更好的答案——这应该是最后的手段。
                      【解决方案30】:

                      这是我测试私有字段的通用函数:

                      protected <F> F getPrivateField(String fieldName, Object obj)
                          throws NoSuchFieldException, IllegalAccessException {
                          Field field =
                              obj.getClass().getDeclaredField(fieldName);
                      
                          field.setAccessible(true);
                          return (F)field.get(obj);
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 2013-09-01
                        • 1970-01-01
                        • 2020-08-03
                        • 2010-11-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2018-02-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多