PHPUnit:断言两个数组相等,但元素的顺序不重要
2022-08-30 06:31:01
当数组中元素的顺序不重要,甚至可能会发生变化时,断言两个对象数组相等的好方法是什么?
当数组中元素的顺序不重要,甚至可能会发生变化时,断言两个对象数组相等的好方法是什么?
您可以使用 PHPUnit 7.5 中添加的 assertEqualsCanonicalization 方法。如果使用此方法比较数组,则这些数组将按 PHPUnit 数组比较器本身进行排序。
代码示例:
class ArraysTest extends \PHPUnit\Framework\TestCase
{
public function testEquality()
{
$obj1 = $this->getObject(1);
$obj2 = $this->getObject(2);
$obj3 = $this->getObject(3);
$array1 = [$obj1, $obj2, $obj3];
$array2 = [$obj2, $obj1, $obj3];
// Pass
$this->assertEqualsCanonicalizing($array1, $array2);
// Fail
$this->assertEquals($array1, $array2);
}
private function getObject($value)
{
$result = new \stdClass();
$result->property = $value;
return $result;
}
}
在较旧版本的 PHPUnit 中,您可以使用未记录的参数$canonicalize assertEquals 方法。如果传递$canonicalize = true,您将获得相同的效果:
class ArraysTest extends PHPUnit_Framework_TestCase
{
public function testEquality()
{
$obj1 = $this->getObject(1);
$obj2 = $this->getObject(2);
$obj3 = $this->getObject(3);
$array1 = [$obj1, $obj2, $obj3];
$array2 = [$obj2, $obj1, $obj3];
// Pass
$this->assertEquals($array1, $array2, "\$canonicalize = true", 0.0, 10, true);
// Fail
$this->assertEquals($array1, $array2, "Default behaviour");
}
private function getObject($value)
{
$result = new stdclass();
$result->property = $value;
return $result;
}
}
最新版本 PHPUnit 的数组比较器源代码:https://github.com/sebastianbergmann/comparator/blob/master/src/ArrayComparator.php#L46
最干净的方法是使用新的断言方法扩展phpunit。但现在这里有一个更简单的方法的想法。未经测试的代码,请验证:
应用中的某个位置:
/**
* Determine if two associative arrays are similar
*
* Both arrays must have the same indexes with identical values
* without respect to key ordering
*
* @param array $a
* @param array $b
* @return bool
*/
function arrays_are_similar($a, $b) {
// if the indexes don't match, return immediately
if (count(array_diff_assoc($a, $b))) {
return false;
}
// we know that the indexes, but maybe not values, match.
// compare the values between the two arrays
foreach($a as $k => $v) {
if ($v !== $b[$k]) {
return false;
}
}
// we have identical indexes, and no unequal values
return true;
}
在测试中:
$this->assertTrue(arrays_are_similar($foo, $bar));