我正在阅读Michelangelo van Dam又名DragonBe的关于Quality Assurance for PHP Projects的精彩演讲。在他的演讲中,他使用Zend-Framework作为一个例子,我在基本层面上熟悉它。
由于我想提高自己,我从单元测试开始,虽然我觉得问题出在ZF方面。
问题:
使用给定的代码工件,只要我指定一个布尔值false
,Zend_Filter或Zend_Validator就会将其更改为null
。我无法弄清楚为什么会这样。
请参阅底部的更新以获取更新的代码并进行测试
首先进行测试
public function goodData() {
return array(
array('DU-IT', 'Sample Description', true, false),
array('Mercüß', 'bla"ß"trager', false, true),
array('Mia123', '728 Tage im Jahr', false, false)
);
}
/**
* @dataProvider goodData()
*/
public function testModelAcceptsValidData($name, $description, $flag_active, $flag_deleted)
{
$data = array(
'id' => 0,
'name' => $name,
'description' => $description,
'flag_active' => $flag_active,
'flag_deleted' => $flag_deleted
);
try {
$this->_model->populate($data);
} catch (Zend_Exception $e) {
$this->fail('Unexpected Exception: '.$e->getMessage());
}
$this->assertSame($data, $this->_model->toArray());
}
模型
public function __construct($props = null)
{
// Set Filters
$this->_filters = array(
'id' => array('Int'),
'name' => array('StringTrim', 'StripTags'),
'description' => array('StringTrim', 'StripTags'),
'flag_active' => array(new Zend_Filter_Boolean()),
'flag_deleted' => array(new Zend_Filter_Boolean())
);
// Set Validators
$this->_validators = array(
'id' => array('Int'),
'name' => array(new Zend_Validate_StringLength(array('min'=>4, 'max'=>50))),
'description' => array(new Zend_Validate_StringLength(array('max'=>5000))),
'flag_active' => array(new Zend_Validate_InArray(array(true, false))),
'flag_deleted' => array(new Zend_Validate_InArray(array(true, false)))
);
// Set Properties
if (!is_null($props)) {
$this->populate($props);
}
}
public function setFlagActive($arg)
{
$input = new Zend_Filter_Input($this->_filters, $this->_validators);
$input->setData(array('flag_active'=>$arg));
if (!$input->isValid('flag_active')) {
throw new Zend_Exception('Invalid FLAG_ACTIVE provided'. gettype($input->flag_active));
}
$this->_flag_active = (bool) $input->flag_active;
return $this;
}
就模型而言,我尝试将flag_active
和flag_deleted
的验证器留空,但这并没有改变我的结果。 phpunit的错误信息保持不变:
Unexpected Exception: Invalid FLAG_ACTIVE providedNULL
尽管NULL是变量的类型,WHENEVER我通过数据提供者goodData()传递false
作为标志的参数(同样也出现在badData中)。
我的猜测这与Zend_Filter有关,但我无法弄清楚这一点。非常感谢提示!
更新 由于德鲁给了一点暗示我已经进行了一些测试,但问题仍然存在。我已将更新的Class和unit测试粘贴到pastebin上以提高可读性。
PHPUnit发出以下错误:You must give a non-empty value for field 'flag_active'
与flag_deleted相同。一半测试的第二个错误是<null> does not match expected type "boolean"
。我被卡住了。无论我使用过滤器还是inArrayValidator(数组(0 =&gt; true,1 =&gt; false)),它都不会改变事物:\
答案 0 :(得分:2)
如果您检查$input->getMessages()
的内容,它应该提供一些解释,说明为什么该特定值通过无效。
当您使用Zend_Filter_Input
时,任何未通过验证的值都不会被其名称神奇地访问(例如$input->flag_active
)。如果未通过验证步骤,则值始终为NULL
。
某些过滤器几乎可以保证在某些情况下的验证(即带有Int验证器的Int过滤器),因为过滤器将过滤数据并返回验证器的有效值。通过hello
过滤器传递Int
会返回0
,即使原始输入数据无效,也可以使用简单的Int
验证程序进行验证。
您最有可能在异常中获得空值的原因是因为该值不可用,因为它没有验证;因此,请检查输入消息以获取有关原因的任何提示。
编辑:
我认为您遇到的问题是Zend_Filter_Input
默认情况下不允许空值。因此,如果进入过滤器的值为false
或NULL
,则会导致过滤器出错。
查看此代码:
<?php
// set up a boolean validator and inarray validator like you have
$filters = array('test' => array(new Zend_Filter_Boolean()));
$validators = array('test' => array(new Zend_Validate_InArray(array(true, false))));
// set up the input filter with default options
$input = new Zend_Filter_Input($filters, $validators);
// our "input" value which is (bool)false
$test = false;
$input->setData(array('test' => $test));
// run through input filter using default values
// should throw error about a non-empty value
if (!$input->isValid('test')) {
echo "Test is not valid. <br />Original Value: ";
var_dump($test);
echo "<br />";
print_r($input->getMessages());
} else {
echo "Test is valid.<br />Original Value: ";
var_dump($test);
echo "<br />Value now: ";
var_dump($input->test);
}
// now allowing empty values...
echo "<hr />\n";
// tell Zend_Filter_Input to allow empty values on input
$options = array(Zend_Filter_Input::ALLOW_EMPTY => true);
// set up new input filter with option
$input = new Zend_Filter_Input($filters, $validators, null, $options);
$input->setData(array('test' => $test));
// run through input filter allowing empty values
// this should NOT throw an error
if (!$input->isValid('test')) {
echo "Test is not valid. <br />Original Value: ";
var_dump($test);
echo "<br />";
print_r($input->getMessages());
} else {
echo "Test is valid.<br />Original Value: ";
var_dump($test);
echo "<br />Value now: ";
var_dump($input->test);
}
所以问题似乎是Zend_Filter_Input不喜欢空值,除非你指定一个选项。因此,将有效(false
)值发送到过滤器会导致错误,除非您将Zend_Filter_Input::ALLOW_EMPTY
设置为true
。