php - 一个仅将参数传递给另一个函数的函数是否应该对该参数进行类型检查?

标签 php unit-testing testing exception phpunit

给定同一类中的以下两个(简单/随机)PHP 方法:

/*
 * @param $a An int to play with
 * @param $b An int to play with
 * @param $c An int to play with
 *
 * @throws InvalidArgumentException when either $a, $b, or $c are not an int
 *
 * @return A new int
 */
public function1($a, $b, $c) {
    if(!is_int($a)) throw new InvalidArgumentException('$a must be an int');
    if(!is_int($b)) throw new InvalidArgumentException('$b must be an int');

    $x = $a * $b;

    $y = $this->function2($c);

    return $x - $y;
}

/*
 * @param $c An int to play with
 *
 * @throws InvalidArgumentException when $c is not an int
 *
 * @return A new int
 */
private function2($c) {
    if(!is_int($c)) throw new InvalidArgumentException('$c must be an int');

   return $c + 1;
}

两部分问题:

  • function1() 是否也应该检查 $c 的参数类型?
  • 测试时,比如使用 PHPUnit,是否足以测试 function2 的错误参数,或者我是否还应该编写第二个测试来测试将错误的 $c 传递给 function1?

除了 function1() 之外,function2() 可能会被其他函数调用。

一方面,我认为函数应该检查提供给它的所有内容。另一方面,我觉得这可能会导致大量重复且(虽然没有这些特定功能)成本高昂的代码。

最佳答案

function1 是否检查参数 c 并不重要,这在很大程度上是一种风格选择。有些人喜欢在函数开始时执行 ALL 检查,因为这意味着函数可以尽快中止,而不会发生任何不必要的处理。如果在调用 function2 之前有重要的处理,那么会有更多的检查理由,但就目前而言,重要的是在实际使用参数之前检查参数。

就您的第二个问题而言,是的,您应该测试将错误参数传递给 function1。就我个人而言,我认为您不应该测试将错误参数传递给 function2。事实上,从单元测试的角度来看,您甚至不应该知道 function2 的存在。

一个类的公共(public)方法决定了公共(public)接口(interface),因此决定了该类的可测试的api。换句话说,如果我是你类的客户端,我可以调用你类的任何公共(public)方法,包括function1。当客户端调用公共(public)方法时,可以测试某些期望(输入/输出/执行的处理),但客户端不应该知道或关心这些期望是否全部通过一种方法或通过使用多种方法得到满足/强制执行方法。因此,从客户的角度来看,您的代码可以这样编写:

/*
 * @param $a An int to play with
 * @param $b An int to play with
 * @param $c An int to play with
 *
 * @throws InvalidArgumentException when either $a, $b, or $c are not an int
 *
 * @return A new int
 */
public function1($a, $b, $c) {
    if(!is_int($a)) throw new InvalidArgumentException('$a must be an int');
    if(!is_int($b)) throw new InvalidArgumentException('$b must be an int');
    if(!is_int($c)) throw new InvalidArgumentException('$c must be an int');

    $x = $a * $b;

    $y = $c + 1;

    return $x - $y;
}

如果您最初是这样编写代码并为此行为编写测试的,那么您可以通过添加 function2 来重构您的代码,以便与知识安全的其他方法共享功能您的公共(public)接口(interface)测试正在确保该类仍然按预期对客户端执行。这就是您不时听到的术语“自信地重构”的来源。

如果您开始测试所有私有(private)方法,那么您将最终将测试与实现(而不是行为)或您的类紧密耦合。这使得您在不破坏测试的情况下重构代码变得更加困难,并且您可能会达到这样的地步,即测试更多的是开销而不是好处。

关于php - 一个仅将参数传递给另一个函数的函数是否应该对该参数进行类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27260923/

相关文章:

php - $_GET 不工作

php - 从 mysql 列中检索和回显多个值

php - 脚本中的 Netbeans SQL 语法突出显示? (例如 PHP)

angular - 异步测试确实遍历了所有功能

java - 对象列表上的 JUnit Mockito ReflectionEquals

PHP 解析错误 : syntax error, 意外的 T_CLASS

node.js - 在同一文件中定义的 Sinon stub 辅助方法

c# - 如何验证模拟对象是否已从模拟列表中删除?

.net - 是否有允许多个继承行为的 BDD 风格的框架?

rest - 如何在 Postman 测试中读取环境变量?