2015-04-02 2 views
1

При модульном тестировании в PHPUnit я попал в ситуацию, когда мне нужно проверить, содержит ли массив хотя бы один объект определенного типа.PHPUnit - проверяет, содержит ли массив объект определенного типа

Вот простой пример того, что я ищу

$obj_1 = new Type1; 
$obj_2 = new Type2; 

$container = array($obj_1, $obj_2); 

// some logic and array manipulation here 

// need something like this 
$this->assertArrayHasObjectOfClass('Type1', $container); 

Очевидно, что я могу сделать это с помощью специального кода, но есть ли утверждение (или их сочетание), который позволяет мне сделать это?

Мне нужно сделать это много раз в нескольких тестах, поэтому, если требуемое утверждение не существует, как мне расширить набор утверждений PHPUnit?

EDIT: индивидуальное решение с признаком

Как предложенному Вейл, я придумал индивидуальное решение для этого, используя черты. Здесь приведен пример с добавлением semplified.

// trait code 
trait CustomAssertTrait 
{ 
    public function assertArrayHasObjectOfType($type, $array, $message = '') { 

     $found = false; 

     foreach($array as $obj) { 
      if(get_class($obj) === $type) { 
       $found = true; 
       break; 
      } 
     } 

     $this->assertTrue($found, $message); 

    } 
} 

// test code 
class CustomTest extends PHPUnit_Framework_TestCase { 
    use CustomAssertTrait; 

    // test methods... 
} 
+0

Было бы неплохо, если бы вы могли бы обеспечить минимальный рабочий пример того, что вы хотите достичь. – martin

+0

Если вы нашли, вы, вероятно, захотите «вырваться» из цикла. – AbraCadaver

+0

Вы можете попробовать [assertInstanceOf()] (https://github.com/sebastianbergmann/phpunit/blob/master/src/Framework/Assert.php#L1236) как [пример] (https://github.com/ sebastianbergmann/PHPUnit/BLOB/Master/тесты/Framework/AssertTest.php # L3835). – acfreitas

ответ

0

Я не думаю, что для этого есть утверждение. Вам нужно будет написать собственный код.

О расширениях утверждений PHPUnit вы можете создать признак с помощью собственного метода утверждения и добавить его к конкретным тестам.

Или посмотрите на этой https://phpunit.de/manual/current/en/extending-phpunit.html

0

Аналогичны ваше решение:

$found = (bool)array_filter(function($v) use ($type) { 
           return get_class($v) === $type; 
          }, $array); 
+0

Это умное решение, чтобы иметь все в одной строке. Но я думаю, что мое решение с вашим предложением (я добавил перерыв в петле foreach), это немного безопаснее. Более того, я не знаю, как закрытие PHP выполняется на низком уровне в случае array_filter. Я имею в виду, что закрытие создается каждый раз, когда оно зацикливается или создается один раз, а затем используется всеми итерациями? –

+0

Создан один раз. array_filter - небольшая оболочка вокруг эффективного кода кода. Это быстрее или быстрее, чем любой php-цикл без раннего выхода. –

0

Если вы проверяете только один объект метод использования assertContains() и место массива или Traversable в качестве второго параметра. Но здесь объект должен иметь те же свойства, что и тот, который вы ищете (например, id, title и т. Д.) ex.

$obj_x = new Type1; 
$this->assertContains($obj_x, $container); 

Если все объекты в массиве или проходимые имеют общего предка или интерфейса, вы можете использовать метод assertContainsOnlyInstancesOf() ех.

$this->assertContainsOnlyInstancesOf(Type1Type2Interface::class, $container); 

https://phpunit.de/manual/5.7/en/appendixes.assertions.html#appendixes.assertions.assertContainsOnlyInstancesOf

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