在phpunit测试中为filter\u input\u数组(input\u POST)设置$\u POST
使用PHPUnit测试控制器时遇到一些问题 到目前为止,我正在编写的代码正在实现在phpunit测试中为filter\u input\u数组(input\u POST)设置$\u POST,php,unit-testing,phpunit,http-post,global,Php,Unit Testing,Phpunit,Http Post,Global,使用PHPUnit测试控制器时遇到一些问题 到目前为止,我正在编写的代码正在实现$\u POST或其他请求变量: $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = array( 'test' => true ); 在我遇到使用filter\u input\u array函数的方法之前,大多数测试都是以这种方式完美运行的: $_SERVER['REQUEST_METHOD'] = 'POST'; $_REQUEST = $_POST = $
$\u POST
或其他请求变量:
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = array(
'test' => true
);
在我遇到使用filter\u input\u array
函数的方法之前,大多数测试都是以这种方式完美运行的:
$_SERVER['REQUEST_METHOD'] = 'POST';
$_REQUEST = $_POST = $GLOBALS['_POST'] = array(
'test' => true
);
// ....
var_dump(filter_input_array(INPUT_POST));
空的
我不愿意从非我的代码中删除filter\u input
函数,但我无法使它们在测试中工作
版本:PHP 5.5.9-1ubuntu4.9(cli)(构建时间:2015年4月17日11:44:57)
Apache/2.4.7(Ubuntu)
PHPUnit 4.6.6由塞巴斯蒂安·伯格曼和贡献者撰写 任何帮助都将不胜感激 编辑2015.05.11 使用
CONTENT\u LENGTH
和CONTENT\u TYPE
设置$\u服务器
,无法解决此问题。我的PHP版本不允许我编写php://stdin
按照PHP5.6.0 chagelog中描述的方式(或我理解的方式),但是文件内容(STDIN,…)
成功了,但无论如何都不起作用
因为这是一个phpunit测试,可能有某种注释或
phpunit.xml
条目我还不知道,可能会以某种方式解决这个问题。这似乎是PHP的一个限制,过滤器输入数组()
不允许在运行时修改$\u POST
数组。有关更多信息,请参阅。解决方法可能是自己使用其中一个并传入$\u POST
数组。如果未设置任何参数,此函数将返回NULL
,而不是NULL值数组。
//请求中未设置POST VAR
$_POST = array();
$args = array('some_post_var' => FILTER_VALIDATE_INT);
$myinputs = filter_input_array(INPUT_POST, $args);
var_dump($myinputs);
Expected Output: array(1) { ["some_post_var"]=> NULL }
实际输出:空
过滤输入数组时,请注意除了FILTER\u REQUIRE\u ARRAY
之外还设置了哪些标志。例如,设置如下标志:
<?php
$filter = array(
'myInputArr' => array('filter' => FILTER_SANITIZE_STRING,
'flags' => array('FILTER_FLAG_STRIP_LOW', 'FILTER_REQUIRE_ARRAY'))
);
$form_inputs = filter_input_array(INPUT_POST, $filter);
?>
。。将导致一个空白的$form_inputs['myInputArr'],无论
$u POST['myInputArr']包含的内容
如果对
filter\u input\u array
的输入只能由初始请求设置,并且不能在运行时更改,那么仍然测试它的唯一方法是通过使用正确的POST数据发出HTTP请求并处理响应,将您的基本测试代理发送到另一个测试脚本
main_test.php:
<?php
$data = array(
'testname' => 'yourtestname',
'some_post_var' => 'some_value'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/proxy_test.php");
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
if ($response == 'pass') {
// test passed
}
实现这一点的一种方法是使用助手方法在内部运行filter\u input\u array
,然后在测试期间模拟此方法以使用类似filter\u var\u array
的其他方法
例如,此用例可以通过以下操作完成:
class Data_Class {
protected function i_use_filters() {
return $this->filter_input_array();
}
protected function filter_input_array() {
return filter_input_array( INPUT_POST );
}
}
class Test_Class extends TestCase {
public function test_filters() : void {
$mock = $this->getMockBuilder( Data_Class::class )
->setMethods( [ 'filter_input_array' ] )
->getMock();
$mock->method( 'filter_input_array' )
->willReturnCallback( function () {
if ( ! isset( $_POST ) ) {
return null;
}
return \filter_var_array( $_POST );
} );
$_POST['test'] = true;
$this->assertTrue( $mock->i_use_filters()['test'] );
}
}
您的两个示例分配的$\u POST
不同。在执行$\u REQUEST=$\u POST=/code>之前,三个变量$\u REQUEST
、$\u POST
的值是多少?它们的空数组。由于这是一个phpunit测试,它在命令行(phpcli)中运行,因此即使web服务器和no$\u请求相关的变量也应该设置,它也不会运行。我在看php本身的单元测试,它们是如何测试filter\u input\u array
的,但这对我一点帮助都没有。看看它是否有帮助?似乎providen bug仍然存在,因为函数返回NULL而不是false或空数组。无论如何,我认为在phpunit中运行这个测试是可能的,因为这个工具在不同的进程中提供了运行脚本的功能,我提供了一个这样的答案,证明在脚本启动时设置POST是可能的。我只是还没有为我的案例找到解决方法。如果我不能理解,很抱歉,但这对我的问题有什么帮助?感谢您建议curl
。这是一种变通办法,但似乎确实有效。另外,您是否可以编辑代理测试($test\u name=
)?看起来是一种方法。我会努力的。不幸的是,它可能不会在我目前的配置中提供代码覆盖率,但目前可以不提供这种覆盖率。
class Data_Class {
protected function i_use_filters() {
return $this->filter_input_array();
}
protected function filter_input_array() {
return filter_input_array( INPUT_POST );
}
}
class Test_Class extends TestCase {
public function test_filters() : void {
$mock = $this->getMockBuilder( Data_Class::class )
->setMethods( [ 'filter_input_array' ] )
->getMock();
$mock->method( 'filter_input_array' )
->willReturnCallback( function () {
if ( ! isset( $_POST ) ) {
return null;
}
return \filter_var_array( $_POST );
} );
$_POST['test'] = true;
$this->assertTrue( $mock->i_use_filters()['test'] );
}
}