gremo
gremo

Reputation: 48899

Fail in asserting about argument types in PHPUnit

Assertion:

$chain->expects($this->once())
   ->method('addMethodCall')
   ->with(
       'addOptionsProvider',
       array(
          $this->isInstanceOf('Symfony\Component\DependencyInjection\Reference'),
          $this->equalTo(7)
       )
   );

$chain is actually a mock object of Definition, and this is the code I'd like to test:

$definition->addMethodCall(
    'addOptionsProvider',
    array(new Reference($id), $priority)
);

I'm beginning PHPUnit, so I really don't know what I'm missing. I'm finding asserting about arguments really hard to understand. I've included an image with the visual difference between the assertion and the actual parameters.

PHPUnit_Framework_ExpectationFailedException : Expectation failed for method name is equal to when invoked 1 time(s) Parameter 1 for invocation Symfony\Component\DependencyInjection\Definition::addMethodCall('addOptionsProvider', Array (...)) does not match expected value.

enter image description here

EDIT: actually, I ended up with this:

$chain->expects($this->once())
    ->method('addMethodCall')
    ->with(
        $this->identicalTo('addOptionsProvider'),
        $this->logicalAnd(
            $this->isType('array'),
            $this->arrayHasKey(0),
            $this->arrayHasKey(1)
        )
    );

But I can't "go" into the array values for making further assertion!

Upvotes: 1

Views: 2367

Answers (1)

edorian
edorian

Reputation: 38961

->with() has a different method signature than you expect it to have.

->with(string|PHPUnit_Framework_Constraint, ...)

meaning that you can't just pass an array in there because PHPUnit isn't "smart" enough to figure out what you mean.

The easiest way to mock this should be:

->with(
   'addOptionsProvider',
   array(
      new Reference(1),
      7
   )
)

as it will then just compare the array.

Another way to mock this (if you need to make method calls on objects and so on) is to use

->with($this->callback(function($arg)  { ... } ));

and make your assertions there.

For a complex example see: mock atLeastOnce with concrete value, the rest not important

Upvotes: 2

Related Questions