Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do hasKeys() in PHP Mockery, or create custom parameter expectations?

Mockery has a method hasKey(), which checks if a given parameter has a certain key. I want to make sure that the passed array has multiple keys. I would also like to assert that the array has x amount of elements.

Is there a built-in way to allow for custom parameter expectations? I tried using a closure that returns true or false based on the given parameter, but that didn't work.

Thanks.

Edit:

Example

$obj = m::mock('MyClass');
$obj->shouldReceive('method')->once()->with(m::hasKey('mykeyname'));

What I'm trying to do is to have more insight into what is passed to the method using with(). I want to assert that an array passed to a method has both key a AND key b. It would be great if I could use a closure somehow to create my own assertion, such as counting the number of array elements.

like image 726
timetofly Avatar asked Feb 01 '26 15:02

timetofly


1 Answers

You can user a custom matcher.

Out of the top of my head (not tested) this could look something like this:

class HasKeysMatcher extends \Mockery\Matcher\MatcherAbstract
{
    protected $expectedNumberOfElements;
    public function __construct($expectedKeys, $expectedNumberOfElements)
    {
        parent::__construct($expectedKeys);
        $this->expectedNumberOfElements =$expectedNumberOfElements;
    }

    public function match(&$actual)
    {
        foreach($this->_expected as $expectedKey){
            if (!array_key_exists($expectedKey, $actual)){
                return false;
            }
        }
        return $this->expectedNumberOfElements==count($actual);
    }

    /**
     * Return a string representation of this Matcher
     *
     * @return string
     */
    public function __toString()
    {
        return '<HasKeys>';
    }

}

and then use it like this:

$obj = m::mock('MyClass'); $obj->shouldReceive('method')->once()->with(new HasKeysMatcher(array('key1','key2'),5));

like image 160
malte Avatar answered Feb 03 '26 06:02

malte