PHPUnit assertEquals严格类型检查

时间:2016-08-11 10:01:50

标签: phpunit assertions

我的目标是确保对象图具有预期的值和类型。我想确保每个值都是预期的类型。

为此,遗憾的是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()同时做两件事(我最多只有经过验证的对象类,而不是参考)。

3 个答案:

答案 0 :(得分:0)

您可以首先检查数组密钥是否存在,然后检查是否有正确的类型,例如:

    $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']);

希望这个帮助

答案 1 :(得分:0)

到目前为止,我想出了以下选项:

/**
 * @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 :(得分:0)

由于您的目标似乎是比较2个数组,
应该注意的是,官方PHP手册中的Array Operators-描述了===对数组运算符的支持

  

$ a === $ b身份如果$ a和$ b具有相同的键/值对,则为TRUE   相同的订单相同类型。 //相同类型仅用于值-不检查键类型

所以您要做的是在一个真正的断言中比较此结果:

$this->assertTrue(['a' => '1', 'b' => '2'] === ['a' => 1, 'b' => '2']);

assertEquals()在您的情况下失败了,因为它完全按照它所说的进行了测试,并使用==-我承认的equal运算符不是很直观,并且带来了一些诸如

$this->assertEquals(321, true); // this would PASS!

对于对象,您应该定义一个完整的独立比较器。

相关问题