我有时觉得人们过度使用可测试性设计,最终得到的代码 80% 的复杂性似乎只是为了让测试更容易。我觉得对于那些在单元测试中变得混乱的东西来说,切换到功能测试通常会更好。
但是对于我放弃的 PHP 超级全局变量。所以我尽量避免在任何框架代码中使用 $_POST 或 $_GET,而是使用参数,或者,如果这使代码太难看,那么使用类成员或静态成员。
所以,你的 get() 函数可以这样重写:
public static function get($name,$default,$GET=null)
{
if($GET===null)$GET=$_GET; //For non-test code
if(!array_key_exists($name,$GET))return $default;
return $GET[$name];
}
那么你的测试就变成了:
public function testGET()
{
$GET=array('test' => 'test value');
$get_value = Input::get('test', '[default value]', $GET);
$this->assertEquals('test value', $get_value);
}
当对 Input::get() 的调用深埋在调用层次结构中时,这很快就会变得很尴尬;那么静态类成员会更好。要使用类成员,可以在 init() 函数中传递 $GET。但是如果有一个init() 函数是不合适的,它可以这样做:
public static $GET=null;
public static function get($name,$default)
{
if(self::$GET===null)self::$GET=$_GET; //Init on first call
if(!array_key_exists($name,self::$GET))return $default;
return $GET[$name];
}
然后测试变成:
public function testGET()
{
Input::$GET=array('test' => 'test value');
$get_value = Input::get('test', '[default value]');
$this->assertEquals('test value', $get_value);
}
除此之外:我喜欢这种方法的另一个(非测试)原因是它允许客户端代码选择使用$_GET、$_POST、$_REQUEST 等。所以我将静态变量命名为@ 987654331@,并有一个init() 函数,用户需要传入$_POST 或$_GET 或任何他们想要的。
您问题的后半部分询问有关测试 PUT 和 DELETE 数据的问题。但是你没有说它是如何在真实代码中处理的。您是否有一些类似于此答案中显示的代码:https://stackoverflow.com/a/5374881/841830
如果是这样,一种方法是模拟此处显示的getContent() 函数,以返回硬编码文本,而不是从php://input 获取它。另一种方法是使用另一个函数(在您的真实类中),主要用于测试,在第一次调用将使用该变量之前进入并设置$this->content。 (那个答案中的$this->content 基本上就像我之前提到的self::$INPUT 变量。)