1

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!

1
  • Difficulty in testing is a product of how it was coded. This an example why TDD should be used, else you have functional code you can't test easily (which generally means it's not very reusable either). new Reference($id) should be mocked, or if a method is used to retrieve that instance, an expectation on that in your test. Commented Dec 22, 2012 at 15:23

1 Answer 1

2

->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

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

2 Comments

Please take a look at my edits. Is that the "right" way, even if more complex?
@Gremo It's correct but the assertions are a little yeah. (As you only assert you have 2 elements on that array and not what they are) but it works. Also the $this->identicalTo('addOptionsProvider') is not really needed as strings will be turned into $this->equals() anyways. But it's of course also correct.

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.