2

I've written a method that basically looks like this:

public function collectData($input, FooInterface $foo) {
   $data = array();
   $data['products']['name'] = $this->some_method();
   if(empty($input['bar'])) {
       $data['products']['type'] = "Baz";
   }
   // hundreds of calls later
   $foo->persist($data);
}

Now I'd like to unit test the collectData method to check if values in $data are set for certain inputs. For object parameters I'd normally use a mock like this:

$mock = $this->getMock('FooInterface');
$mock->expects($this->once())
             ->method('persist')
             ->with($this->identicalTo($expectedObject));

But how would I test for certain nested array keys (for example, if $data['products']['prices']['taxgroup'] is 1), ignoring all other keys that might be in the array? Does PHPUnit or Mockery provide such checks? Or could they easily extended to provide such a check?

Or is it better to do what I'm doing at the moment: create my own FooClassMock class that implements FooInterface and just stores the data in the persist call?

2 Answers 2

1

You have one more option, but only if you use PHPUnit >= 3.7. There is a callback assertion and you can use it like this:

$mock = $this->getMock('FooInterface', array('persist');
$mock->expects($this->once())
         ->method('persist')
         ->with($this->callback(function($object) {
             // here you can do your own complex assertions

             return true|false;
         }));

Here is more details:

https://github.com/sebastianbergmann/phpunit/pull/206

Sign up to request clarification or add additional context in comments.

Comments

1

It turns out, there is a way - I can create my own constraint class. After that, it's easy:

$constraint = new NestedArrayConstraint(
    array('products', 'prices', 'taxgroup'),
    $this->equalTo(1)
);
$mock = $this->getMock('FooInterface', array('persist'));
$mock->expects($this->once())
             ->method('persist')
             ->with($constraint);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.