Mat*_*att 3 php phpunit unit-testing httprequest
我正在编写一个 MVC 框架,它利用一个库来帮助管理输入变量(例如 get、post 等)。
现在,我正在通过分别将 POST 和 GET 变量的值强制写入 $_POST 和 $_GET 超全局变量来测试 POST 和 GET 变量,但在测试 PUT 和 DELETE 请求变量时遇到了障碍。
例子:
public function testGET()
{
$_GET['test'] = 'test value';
$get_value = Input::get('test', '[default value]');
assertEquals('test value', $get_value);
}
Run Code Online (Sandbox Code Playgroud)
是否有一个好方法来模拟/模拟这些变量或使用各种可用的方法(特别是 GET、POST、PUT、DELETE)来模拟 HTTP 请求?
我有时觉得人们过度使用可测试性设计,最终得到的代码中 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];
}
Run Code Online (Sandbox Code Playgroud)
那么你的测试就变成:
public function testGET()
{
$GET=array('test' => 'test value');
$get_value = Input::get('test', '[default value]', $GET);
$this->assertEquals('test value', $get_value);
}
Run Code Online (Sandbox Code Playgroud)
当对 Input::get() 的调用深埋在调用层次结构中时,这很快就会变得尴尬;那么静态类成员更好。要使用类成员,可以在函数中传递 $GET init()。但如果有一个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];
}
Run Code Online (Sandbox Code Playgroud)
然后测试就变成:
public function testGET()
{
Input::$GET=array('test' => 'test value');
$get_value = Input::get('test', '[default value]');
$this->assertEquals('test value', $get_value);
}
Run Code Online (Sandbox Code Playgroud)
旁白:我喜欢这种方法的另一个(非测试)原因是它允许客户端代码选择使用$_GET、$_POST、$_REQUEST等。所以我将命名静态变量self::$INPUT,并有init()一个用户需要传入的函数$_POST或者$_GET或者他们想要的任何东西。
您问题的后半部分询问有关测试 PUT 和 DELETE 数据的问题。但是您没有说明实际代码中如何处理它。您是否有一些类似于此答案中显示的代码:/sf/answers/376241701/
如果是这样,一种方法是模拟该getContent()函数(如此处所示)以返回硬编码文本,而不是从php://input. 另一种方法是使用另一个函数(在您的实际类中),主要用于测试,该函数$this->content在将使用该变量的第一个调用之前进入并设置。($this->content这个答案基本上就像self::$INPUT我之前提到的变量一样。)