PHPUnit assertEquals 严格类型检查
PHPUnit assertEquals strict type check
我的objective是确保对象图具有预期的值和类型。我想确保每个值都是预期的类型。
为此,assertEquals()
很遗憾没有用:
$this->assertEquals(
[ 'prop' => '0' ],
[ 'prop' => 0 ]
);
// -> no failures
在这种情况下,assertSame()
效果很好:
$this->assertSame(
[ 'prop' => '0' ],
[ 'prop' => 0 ]
);
// Failed asserting that Array &0 (
// 'prop' => 0
// ) is identical to Array &0 (
// 'prop' => '0'
// ).
assertSame()
的问题在于它还检查对象的引用:
$this->assertSame(
(object) [ 'prop' => 0 ],
(object) [ 'prop' => 0 ]
);
// Failed asserting that two variables reference the same object.
我有什么选择?
另外,我不确定为什么要这样设计 - 对我来说,感觉 assertSame()
同时做两件事(我最多有验证过的对象 class, 不是引用).
您可以先检查数组键是否存在,然后检查类型是否正确,例如:
$this->assertArrayHasKey('prop', $input);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_INT, $input['prop']);
// or more simply as this->assertTrue(is_int($new_id));
$this->assertEquals(0, $input['prop']);
希望对您有所帮助
到目前为止,我想到了以下选项:
/**
* @param mixed $expected
* @param mixed $actual
* @param string $message
*/
public function assertObjectGraph($expected, $actual, $message = '')
{
$expected = $this->convertObjectsToHashes($expected);
$actual = $this->convertObjectsToHashes($actual);
$this->assertSame($expected, $actual, $message);
}
/**
* @param mixed $value
* @return mixed
*/
private function convertObjectsToHashes($value)
{
if (is_object($value)) {
$value = ['__CLASS__' => get_class($value)] + get_object_vars($value);
}
if (is_array($value)) {
$value = array_map([$this, __FUNCTION__], $value);
}
return $value;
}
示例:
$this->assertObjectGraph(
(object) [ 'prop' => 0 ],
(object) [ 'prop' => 0 ]
);
// -> ok
$this->assertObjectGraph(
(object) [ 'prop' => 0 ],
(object) [ 'prop' => '0' ],
);
// Failed asserting that Array &0 (
// '__CLASS__' => 'stdClass'
// 'prop' => '0'
// ) is identical to Array &0 (
// '__CLASS__' => 'stdClass'
// 'prop' => 0
// ).
class Test{public $prop = 0;}
$this->assertObjectGraph(
(object) [ 'prop' => 0 ],
new Test()
);
// Failed asserting that Array &0 (
// '__CLASS__' => 'Test'
// 'prop' => 0
// ) is identical to Array &0 (
// '__CLASS__' => 'stdClass'
// 'prop' => 0
// ).
由于您的目标似乎是比较 2 个数组,
需要注意的是,在官方 PHP 手册中 - Array Operators - 描述了对数组 ===
运算符的支持
$a === $b Identity TRUE if $a and $b have the same key/value pairs in
the same order and of the same types. // same types is only for values - does not check key types
那么你要做的是在一个真实的断言中比较这个结果:
$this->assertTrue(['a' => '1', 'b' => '2'] === ['a' => 1, 'b' => '2']);
assertEquals()
在你的案例中失败了,因为它完全按照它说的做,它用 ==
测试 - 我承认的 equal
运算符不是很直观并且带来了一些时髦的东西比如
$this->assertEquals(321, true); // this would PASS!
至于对象,你应该定义一个完整的独立比较器。
我的objective是确保对象图具有预期的值和类型。我想确保每个值都是预期的类型。
为此,assertEquals()
很遗憾没有用:
$this->assertEquals(
[ 'prop' => '0' ],
[ 'prop' => 0 ]
);
// -> no failures
在这种情况下,assertSame()
效果很好:
$this->assertSame(
[ 'prop' => '0' ],
[ 'prop' => 0 ]
);
// Failed asserting that Array &0 (
// 'prop' => 0
// ) is identical to Array &0 (
// 'prop' => '0'
// ).
assertSame()
的问题在于它还检查对象的引用:
$this->assertSame(
(object) [ 'prop' => 0 ],
(object) [ 'prop' => 0 ]
);
// Failed asserting that two variables reference the same object.
我有什么选择?
另外,我不确定为什么要这样设计 - 对我来说,感觉 assertSame()
同时做两件事(我最多有验证过的对象 class, 不是引用).
您可以先检查数组键是否存在,然后检查类型是否正确,例如:
$this->assertArrayHasKey('prop', $input);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_INT, $input['prop']);
// or more simply as this->assertTrue(is_int($new_id));
$this->assertEquals(0, $input['prop']);
希望对您有所帮助
到目前为止,我想到了以下选项:
/**
* @param mixed $expected
* @param mixed $actual
* @param string $message
*/
public function assertObjectGraph($expected, $actual, $message = '')
{
$expected = $this->convertObjectsToHashes($expected);
$actual = $this->convertObjectsToHashes($actual);
$this->assertSame($expected, $actual, $message);
}
/**
* @param mixed $value
* @return mixed
*/
private function convertObjectsToHashes($value)
{
if (is_object($value)) {
$value = ['__CLASS__' => get_class($value)] + get_object_vars($value);
}
if (is_array($value)) {
$value = array_map([$this, __FUNCTION__], $value);
}
return $value;
}
示例:
$this->assertObjectGraph(
(object) [ 'prop' => 0 ],
(object) [ 'prop' => 0 ]
);
// -> ok
$this->assertObjectGraph(
(object) [ 'prop' => 0 ],
(object) [ 'prop' => '0' ],
);
// Failed asserting that Array &0 (
// '__CLASS__' => 'stdClass'
// 'prop' => '0'
// ) is identical to Array &0 (
// '__CLASS__' => 'stdClass'
// 'prop' => 0
// ).
class Test{public $prop = 0;}
$this->assertObjectGraph(
(object) [ 'prop' => 0 ],
new Test()
);
// Failed asserting that Array &0 (
// '__CLASS__' => 'Test'
// 'prop' => 0
// ) is identical to Array &0 (
// '__CLASS__' => 'stdClass'
// 'prop' => 0
// ).
由于您的目标似乎是比较 2 个数组,
需要注意的是,在官方 PHP 手册中 - Array Operators - 描述了对数组 ===
运算符的支持
$a === $b Identity TRUE if $a and $b have the same key/value pairs in the same order and of the same types. // same types is only for values - does not check key types
那么你要做的是在一个真实的断言中比较这个结果:
$this->assertTrue(['a' => '1', 'b' => '2'] === ['a' => 1, 'b' => '2']);
assertEquals()
在你的案例中失败了,因为它完全按照它说的做,它用 ==
测试 - 我承认的 equal
运算符不是很直观并且带来了一些时髦的东西比如
$this->assertEquals(321, true); // this would PASS!
至于对象,你应该定义一个完整的独立比较器。