php - Consecutive calls callback called more times than expected

835

Before I ask this question please keep in mind this is a greatly simplified version of my actual test case.

I am mocking an interface with the purposes of collecting the arguments a certain method was called with. Here is my code:

interface NormalInterface {
 public function functionWithOneParameter($parameter);
}  

class NormalInterfaceTest {
    public function testBasicMockCallback() {
        $mock = $this->getMockForAbstractClass(NormalInterface::class);
        $names = [];
        $cb = function ($name) use (&$names) {
           $names[] = basename($name);
           return true;
        };
        $mock->expects($this->exactly(4))
            ->method("functionWithOneParameter")
            ->withConsecutive([ $this->callback($cb) ],[ $this->callback($cb) ],[ $this->callback($cb) ],[ $this->callback($cb) ])
            ->willReturn(true,true, true, true);
       $mock->functionWithOneParameter("one");
       $mock->functionWithOneParameter("two");
       $mock->functionWithOneParameter("three");
       $mock->functionWithOneParameter("four");
       // If the test ends here it works fine
       $this->assertCount(4, $names); 
   }
}

The above test works without line$this->assertCount(4, $names) which means that the mock method is called exactly 4 times.

However with that line I get:

Failed asserting that actual size 14 matches expected size 4.

The actual content of$names is:

array:14 [
  0 => "one", 
  1 => "one", 2 => "two",
  3 => "one", 4 => "two", 5 => "three"
  6 => "one", 7 => "two", 8 => "three", 9 => "four"
  10 => "one", 11 => "two", 12 => "three", 13 => "four"
]

I would think that the callback would be called 4 times one for each function call, but apparently it is called 14 times. Am I doing something wrong? Am I fundamentally misunderstanding how this is working?

Update:

The issue is resolved if I replace thewithConsecutive with a simple:with($this->callback($cb))->willRetrurn(true) which in this particular case is equivalent but in the cases where I want each consecutive call do check something different this will not work. I feel like I'm missing something very fundamental about either how PHPUnit tests consecutive call parameters.

People are also looking for solutions to the problem: php - Zend Framework 3 BaseInputFilter::setData() throws InvalidArgumentException

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.