单元测试和封装

时间:2010-01-08 07:37:44

标签: php unit-testing encapsulation

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

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

我找到了关于这个主题的this文章。本文的结论是使用反射来测试私有方法。

你如何反对这个问题?

6 个答案:

答案 0 :(得分:11)

你应该在自己的类中拥有逻辑,然后对该类进行单元测试,这样你就不必通过html来测试逻辑。

通常:

你永远不应该测试私有方法。存在私有方法是为了使公共方法通过测试。

如果您可以删除私有方法而不破坏公共方法,则不需要私有方法并可以删除它们。

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

如果你遵循TDD的做法,就很难进入这种情况,因为每行代码都是为了使单元测试通过而编写的。你班上应该没有“流浪”代码。

答案 1 :(得分:2)

我同意Tormod;私有方法不应该被测试。将逻辑与表示分开是一个好主意,并允许您与表示分开测试逻辑。此外,编写逻辑测试是捕获逻辑和表示未正确分离的微妙案例的一种非常好的方法。

(使用反射来测试私有方法对我来说听起来真是个坏主意。)

答案 2 :(得分:1)

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

封装是关于最大限度地减少具有最高变化传播概率的潜在依赖性的数量。

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

它们实际上是正交的:既不应该影响另一个。公开私有方法只是为了测试它不是一个好主意:那个单元测试不必要地降低了你的封装。

将整个源代码复制到测试目录,然后删除修饰符的所有实例“private”。然后将您的测试写入此deprivatised目录。这使单元测试与封装问题脱钩。

使用如下脚本自动执行此复制,剥夺和单元测试。

此致

!/斌/庆典

rm -rf code-copy

echo创建代码复制...

mkdir代码复制

cp -r ../www code-copy /

for find code-copy -name "*php" -follow;做

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

完成

php run_tests.php

答案 3 :(得分:0)

计算值和条件是您的业务逻辑。 业务逻辑比可视化表示更稳定。你应该测试一个定义良好的接口。如果您通过GUI和GUI更改测试代码,这将安全地更改您的测试。 (您也可以添加其他客户端。)

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

这是nice article为什么集成测试不起作用。 (您的测试实际上不是单元测试。它测试应用程序的两个方面。)

使用此设置不会有私有方法进行测试。

答案 4 :(得分:0)

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

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

这样你就可以在你的单元测试中调用方法但是文档(不强制执行)它是一个私有方法。这在某些团队中效果很好,但并非总体而言。

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

答案 5 :(得分:0)

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