3

我对 TDD 相当陌生,并且在单元测试方面经验不足,因此提出了这个问题。我有这个用 PHP 编写的遗留函数

function foo(){
   x = bar();
   y = baz();
   if (x > y)
     return 'greater';
   return 'lesser';
}

如果 x(bar() 返回的值)总是大于 y(baz() 返回的值),我将永远无法测试“较小”的返回语句。

我应该怎么做才能覆盖这两个测试用例并实现 100% 的代码覆盖率?将 foo() 重新定义为 foo(x, y) 用于依赖注入钩子不是遗留代码的选项。

4

2 回答 2

1

我假设foo,bar并且baz都是全局函数。(如果它们是一个类的一部分,您希望使用 PHPUnit 的模拟功能)。

我之前写过关于如何使用 pecl 扩展来替换内置函数的博客:http: //darrendev.blogspot.jp/2012/07/mock-socket-in-php.html

本文展示了一种非常有趣的使用命名空间的替代方法:http: //marcelog.github.io/articles/php_mock_global_functions_for_unit_tests_with_phpunit.html

看来您需要将旧代码包装在顶部带有命名空间声明的文件中。我不知道这对你来说是否是一个阻碍。

于 2013-08-21T23:32:37.907 回答
0

由于 bar() 和 baz() 不接受输入参数,它们要么返回一个常量(你可以立即将 foo() 重构为 { return 'greater' } ;或者它们依赖于一些外部变量。在那个案例,做类似的事情

 function testFooReturnsGreater() {
     setEnvironmentSoBarIsGreaterThanBaz()
     assert ("greater".equals(foo())
 }

 function testFooReturnsLesser() {
    setEnvironmentSoBarIsLesserThanBaz()
    assert("lesser".equals(foo())
}

由于您说 bar() > baz() 除非是圣诞节,否则 setEnvironmentxxx() 固定装置将需要更改程序对当前日期的概念(希望您可以模拟一些东西,而不是实际的系统时钟)。

于 2013-08-21T14:55:48.843 回答