代码之家  ›  专栏  ›  技术社区  ›  Ikke

单元测试和封装

  •  2
  • Ikke  · 技术社区  · 15 年前

    我正在尝试进行单元测试,但有一件事困扰着我。

    我有一个PHP类,我想对其进行单元测试。它需要一些参数,然后输出HTML。问题是,主要功能是计算一些值和条件,我想测试这些值和条件。但是我把它放在一个私有方法中,因为通常没有人需要知道这个方法。但是这样我就不可能对类进行单元测试,因为我无法测试方法的结果。

    我找到了 this 有关主题的文章。本文的结论是利用反射检验私有方法。

    你对这个问题有什么看法?

    6 回复  |  直到 15 年前
        1
  •  11
  •   Tormod    15 年前

    您应该在自己的类中拥有逻辑,然后对该类进行单元测试,因此您不必通过HTML来测试逻辑。

    通常情况下:

    您不应该测试私有方法。为了使公共方法通过测试,存在私有方法。

    如果可以在不破坏公共方法的情况下删除私有方法,则不需要私有方法,可以删除它们。

    如果在不破坏公共方法的情况下无法删除私有方法,那么将测试私有方法。

    如果您遵循TDD的实践,将很难进入这种情况,因为每行代码都是为了让单元测试通过而编写的。在你的班级里不应该有“杂散”的代码。

        2
  •  2
  •   JesperE    15 年前

    我同意托莫德的观点;私人方法不应该被测试。一般来说,将逻辑与表示分离是一个好主意,它允许您单独测试逻辑与表示。此外,为逻辑编写测试是一种非常好的方法,可以捕获逻辑和表示没有正确分离的细微情况。

    (使用反射来测试私有方法对我来说是一个非常糟糕的主意。)

        3
  •  1
  •   Ed Kirwan    15 年前

    单元测试是为了提高执行正确性的概率。

    封装是以最高的变更传播概率最小化潜在依赖项的数量。

    单元测试是关于运行时的,封装是关于源代码的。

    它们实际上是正交的:两者都不应影响另一个。公开一个私有方法来测试它并不是一个好主意:那就是单元测试不必要地降低了封装。

    将整个源代码复制到一个测试目录,然后删除修饰符“private”的任何和所有实例,然后将测试写到这个被剥夺的目录中。这将单元测试与封装问题分离。

    使用如下脚本自动执行复制、取消满足和单元测试。

    当做,

    预计起飞时间。

    !/BI/BASH

    RM-射频代码副本

    echo正在创建代码副本…

    代码拷贝

    CP-R../WWW代码副本/

    因为我在 find code-copy -name "*php" -follow

    sed -i 's/private/public/g' $i
    

    完成

    php运行测试.php

        4
  •  0
  •   Thomas Jung    15 年前

    计算值和条件是您的业务逻辑。这个 业务逻辑更加稳定 而不是视觉表现。您应该根据定义良好的接口进行测试。这将保护您对您的测试所做的更改,如果您通过GUI和GUI更改来测试代码,那么这些更改是必需的。(您还可以添加其他客户端。)

    如果您想测试渲染(并且应该单独进行)。

    这里有一个 nice article 为什么集成测试不起作用。(你的测试不是真正的单元测试。它测试应用程序的两个方面。)

    有了这个设置,就不会有私有方法来测试了。

        5
  •  0
  •   philant    15 年前

    测试私有方法的常见解决方案是将它们提取到新的类中并委托。这是托姆罗德的建议,但你评论说这对你没有任何意义。

    您还可以做的是将该方法公开,但要中继某种命名约定来标记其隐私:例如 privateGetNumberOfPages() ,或 _getNumberOfPages() . 这将是 道德灌输 :这不会阻止任何人调用该方法,但没有人可以说他不知道它是私有的。

    这样,您就可以在单元测试中调用该方法,但文档(而不是强制)它是一个私有方法。这在一些团队中很有效,但并非全部。

    另一种可能性,尽管不是最好的,但在设计上,是使方法受到保护,并让测试用例类从被测试类继承,以便测试可以调用该方法并强制封装。我不确定这在PHP中是否可行。

        6
  •  0
  •   J. B. Rainsberger    15 年前

    我发现,如果我想测试一个私有方法,那么它最终会变得足够复杂,足以保证迁移到一个新的类并成为公共的。我通常遵循以下步骤:将方法公开,彻底测试它,注意在测试中创建的重复,重构以将新的公共方法推出到新的类中。