Given the following class:
<?php class Example { private $Other; public function __construct ($Other) { $this->Other = $Other; } public function query () { $params = array( 'key1' => 'Value 1' , 'key2' => 'Value 2' ); $this->Other->post($params); } }
And this testcase:
<?php require_once 'Example.php'; require_once 'PHPUnit/Framework.php'; class ExampleTest extends PHPUnit_Framework_TestCase { public function test_query_key1_value () { $Mock = $this->getMock('Other', array('post')); $Mock->expects($this->once()) ->method('post') ->with(YOUR_IDEA_HERE); $Example = new Example($Mock); $Example->query(); }
How do I verify that $params
(which is an array) and is passed to $Other->post()
contains a key named ‘key1’ that has a value of ‘Value 1’?
I do not want to verify all of the array – this is just a sample code, in actual code the passed array has a lot more values, I want to verify just a single key/value pair in there.
There is $this->arrayHasKey('keyname')
that I can use to verify that the key exists.
There is also $this->contains('Value 1')
, which can be used to verify that the array has this value.
I could even combine those two with $this->logicalAnd
. But this of course does not give the desired result.
So far I have been using returnCallback, capturing the whole $params and then doing asserts on that, but is there perhaps another way to do what I want?
Advertisement
Answer
I ended up creating my own constraint class, based on the attribute one
<?php class Test_Constraint_ArrayHas extends PHPUnit_Framework_Constraint { protected $arrayKey; protected $constraint; protected $value; /** * @param PHPUnit_Framework_Constraint $constraint * @param string $arrayKey */ public function __construct(PHPUnit_Framework_Constraint $constraint, $arrayKey) { $this->constraint = $constraint; $this->arrayKey = $arrayKey; } /** * Evaluates the constraint for parameter $other. Returns TRUE if the * constraint is met, FALSE otherwise. * * @param mixed $other Value or object to evaluate. * @return bool */ public function evaluate($other) { if (!array_key_exists($this->arrayKey, $other)) { return false; } $this->value = $other[$this->arrayKey]; return $this->constraint->evaluate($other[$this->arrayKey]); } /** * @param mixed $other The value passed to evaluate() which failed the * constraint check. * @param string $description A string with extra description of what was * going on while the evaluation failed. * @param boolean $not Flag to indicate negation. * @throws PHPUnit_Framework_ExpectationFailedException */ public function fail($other, $description, $not = FALSE) { parent::fail($other[$this->arrayKey], $description, $not); } /** * Returns a string representation of the constraint. * * @return string */ public function toString () { return 'the value of key "' . $this->arrayKey . '"(' . $this->value . ') ' . $this->constraint->toString(); } /** * Counts the number of constraint elements. * * @return integer */ public function count () { return count($this->constraint) + 1; } protected function customFailureDescription ($other, $description, $not) { return sprintf('Failed asserting that %s.', $this->toString()); }
It can be used like this:
... ->with(new Test_Constraint_ArrayHas($this->equalTo($value), $key));