【问题标题】:Function Structure vs Unit Testing Private Function函数结构与单元测试私有函数
【发布时间】:2015-11-15 22:22:19
【问题描述】:

我有一个其他人编写的函数,它在函数内部创建了一个 cURL 包装器对象。下面是简化版

public function getCodes()
{
    //do some stufff

    $communicator = new Communicator();
    $result = $communicator->call($this->API_KEY);

    //do some stuff with $result
}

我的任务是学习 PHPUnit 并为这种类型的代码编写测试。在这样做的过程中,我发现当对象是在函数内部创建时,很难测试这样的函数,而且测试不应该需要任何外部通信才能工作。

我们希望像许多项目一样将我们的测试推送到 git,但我们不想意外或故意将我们的 API 凭据推送到 git。

所以我的解决方案是让 getCodes() 公开,但将其作为接受 Communicator 对象作为参数的私有函数的包装器。然后我可以使用模拟 Communicator 对象测试私有方法。

但这意味着 getCodes 永远不会经过测试(我的老板想要 100% 的代码覆盖率),而且我还了解到,在大多数情况下,您不应该为私有函数编写测试。

所以我的问题基本上是,如何通过 API 调用为这样的函数编写测试。

【问题讨论】:

  • 我认为您的解决方案没有任何问题。代码是经过测试的,不是吗? :)
  • 是的,但如果我不需要或有更好的方法,我不想实施黑客攻击。
  • 真的是 hack。您重组了代码,新代码在设计方面很有意义。
  • 100% 的代码覆盖率——包括最琐碎的一个班轮方法?嗯...
  • 同意@bayou.io,你的老板需要更深入地了解代码覆盖的真正含义。还要避免单元测试私有函数。出于某种原因,这些方法是私有的。

标签: php dependency-injection phpunit


【解决方案1】:

我真的建议重写代码以通过构造函数注入 Communicator 对象。 如果您已经发现为某事编写测试存在很大问题,那么这是一个非常强烈的信号,需要重新设计当前的实现。

另一件事是你不应该测试你的私人。 Sebastian Bergmann 前段时间在他的博客上写了一篇关于此的文章,结论是 - 可能只是不好(https://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html)。

完全不同的是,我认为您的测试不应超出系统的边界。那就是 - 模拟连接到外部系统的所有内容。此类测试可能会因各种原因而失败,仅从运行测试的角度来看,这些原因是有效的。

您还提到了报道。不幸的是,我希望每个人都会同意这一点——你不能在开始使用原生 PHP 资源的那一刻拥有它(除了像 FS 这样的小例外)。您必须了解 curl、ssh、ftp 等无法进行单元测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 2010-09-23
    • 2014-01-29
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多