如何为同一属性测试多个值?
class Test {
private $_optionalValue = null;
function setValue(String $optionalValue)
{
$this->_optionalValue = $optionalValue;
}
}
所以在这里,“$ _optionalValue”可能是NULL或用户定义的值,但是当我用phpunit检查时这样:
$optionalValue = PHPUnit_Util_Class::getObjectAttribute($my_object, '_optionalValue');
$this->assertThat(
$optionalValue,
$this->logicalXor(
$this->assertNull($optionalValue),
$this->logicalAnd(
$this->assertAttributeInternalType('string', '_optionalValue', $optionalValue),
$this->assertRegExp('/[0-9]{2}:[0-9]{2}:[0-9]{2}/', (string) $optionalValue)
)
)
);
Regexp断言失败,因为$ optionalValue不是String(默认情况下为null)
答案 0 :(得分:2)
您正在调用assertThat
内部进行断言,但您需要构建并传入约束。所有以assert
开头的方法都会立即评估该值,并在不匹配时抛出异常。每个断言都有一个相应的约束类,有些具有工厂方法。
$optionalValue = PHPUnit_Util_Class::getObjectAttribute($my_object, '_optionalValue');
$this->assertThat(
$optionalValue,
$this->logicalXor(
$this->isNull(),
$this->logicalAnd(
new PHPUnit_Framework_Constraint_IsType('string'),
new PHPUnit_Framework_Constraint_PCREMatch('/[0-9]{2}:[0-9]{2}:[0-9]{2}/')
)
)
);
顺便说一句,我同意a)你最好不要像这样测试内部状态,b)你应该设计你的测试,以便你知道期望的值。每个测试都应该将系统置于单个预期状态。即使使用随机数的代码也应该使用存根替换固定序列。任何允许多种可能性的测试都是可疑的。
答案 1 :(得分:1)
你正在测试一个通常应该避免的对象的私有属性,因为它是单元的内部,你不应该关心它。
如果您的单位需要验证该类的值,则通常可能会验证某种类型的值。
因此,您可以将验证的逻辑封装到它自己的单元中,例如验证者:
class FooValueValidator implements Validator {
/**
* @var string
*/
private $value;
/**
* @var string
*/
private $regex = '/[0-9]{2}:[0-9]{2}:[0-9]{2}/';
public function __construct($value) {
$this->value = $value;
}
/**
* @return bool
*/
public function isValid() {
if (is_null($this->value)) {
return TRUE;
}
if (!is_string($this->value)) {
return FALSE;
}
$result = preg_match($this->pattern, $this->value);
if (FALSE === $result) {
throw new Exception(sprintf('Regular expression failed.'));
}
return (bool) $result;
}
}
然后,您可以为验证器编写单元测试。然后您就知道验证器有效,您可以随意使用它。
class Test {
private $_optionalValue = null;
/**
* @var Validator
*/
private $_validator;
public function __construct(Validator $validator) {
$this->_validator = $validator;
}
function setValue(String $optionalValue)
{
if (!$this->validator->isValid($optionalValue)) {
throw new InvalidArgumentException(sprintf('Invalid value "%s".', $optionalValue));
}
$this->_optionalValue = $optionalValue;
}
}