【发布时间】:2015-01-31 09:05:15
【问题描述】:
给定同一类中的以下两个(简单/随机)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?
function2()有可能被function1()以外的其他函数调用。
一方面,我认为函数应该检查赋予它的所有内容。另一方面,我觉得这可能会导致大量重复且(虽然没有这些特定功能)成本高昂的代码。
【问题讨论】:
-
我认为没有一个正确答案。我喜欢史蒂夫麦康奈尔建议的方法 - 检查公共方法中的所有参数,而内部实现应该假设所有数据都是有效的。关于测试,IMO 第二种方式会过度测试,所以不需要。
-
@RomaKliuchko 我也喜欢这样,但是这样做会阻止我为私有方法编写完整的单元测试,不是吗?我觉得我应该能够完全测试 method1 而无需调用 method2 来测试 method1 的参数。
-
如果 function2() 可以被其他方法调用,那么将
$c参数移动到类属性并为其创建 setter 方法可能是有意义的。使用这种方法,您只需测试一次setC($c)方法即可避免代码重复。 -
我同意。我也不认为有正确的答案。但是,因为评论清楚地指出 C 是一个 int 并且它会在 A、B 或 C 上引发异常。我认为这是你不应该破坏的信任。当然,异常仍然会被抛出并冒泡,但对我来说,代码越可读和易理解越好。我想我可以争辩说,你可能想以同样的方式对另一个函数进行单元测试。可能更容易看到所有内容都已涵盖,并且更容易测试单个方法,而无需弄清楚要调用哪个其他方法。
-
您在
function2中的代码引用$a,而不是$c我假设这是错字,但我没有更新它,因为我真的不喜欢更新其他人代码示例...
标签: php unit-testing testing exception-handling phpunit