2016-08-11 5 views
3

Моя цель - обеспечить, чтобы граф объекта ожидал значений и типов. Я хочу, чтобы каждое значение имело ожидаемый тип.PHPUnit assertEquals строгий контроль типа

С этой целью 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() делает две вещи сразу (я уже не более проверить класс объекта, а не ссылки) ,

ответ

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

надежда эта помощь

+0

Это легко, если это проверка на одно свойство, но не столько для всего графа объектов. – Christian

+0

привет, христианин, конечно. Но таким образом вы можете напрямую указать на проблему (тип вместо значения поля), а не на большой граф объектов, которые отличаются друг от друга. – Matteo

Смежные вопросы