Reputation: 36
While unit testing in PHPUnit, I'm in a situation where I need to check if an array contains al least one object of a specific type.
Here's a trivial example of what I'm looking for
$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 );
Obviously I can do that with custom code, but is there any assertion (or combination of them) which allows me to do that?
I need to do that many times in multiple tests so, if the assertion I need doesn't esist, how do I extend the set of PHPUnit assertions?
EDIT: custom solution with trait
As suggested by Vail, I came up with a custom solution for this using traits. Here's a semplified version.
// 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...
}
Upvotes: 2
Views: 8440
Reputation: 483
Answering since I was looking for an info too and found that while digging in methods list:
9.5.13
assertContainsOnly
$this->assertContainsOnly(Dto::class, $this->provider->provide());
Upvotes: 1
Reputation: 79014
Similar to your solution:
$found = (bool)array_filter($array, function($v) use ($type) {
return get_class($v) === $type;
});
Upvotes: 0
Reputation:
If you check only one object use method assertContains() and place array or Traversable as second parameter. But here object must have same properties as one you are looking for (eg. id, title, etc.) ex.
$obj_x = new Type1;
$this->assertContains($obj_x, $container);
If all objects in array or Traversable have same ancestor or interface, you can use method assertContainsOnlyInstancesOf() ex.
$this->assertContainsOnlyInstancesOf(Type1Type2Interface::class, $container);
Upvotes: 6
Reputation: 608
I don`t think that there is an assertion for this. You will need to write some custom code.
About extendig PHPUnit assertions you could create trait with your own assertion method and add it to specific tests.
Or look at this https://phpunit.de/manual/current/en/extending-phpunit.html
Upvotes: 0