mmmm
mmmm

Reputation: 3938

Method was expected to be called 1 times, actually called 0 times [PHPUnit]

I've been testing, adding and removing lines to see where the problem is. I've managed to cut so many lines that essentially my test looks like that ( of course to see what is wrong, I'm aware this isn't proper test ):

public function test()
{
     $invoice = new Invoice();
     $invoiceRepository = $this
            ->getMockBuilder('\Doctrine\ORM\EntityRepository')
            ->disableOriginalConstructor()
            ->getMock();
      $invoiceRepository->expects($this->once())
            ->method('findOneByNextNote')
            ->will($this->returnValue($invoice));

      $invoiceRepository->findOneByNextNote();
}

and still doesn't work! I'm getting an error from the title:

Expectation failed for method name is equal to < string:findOneByNextNote > when invoked 1 time(s). Method was expected to be called 1 times, actually called 0 times.

What am I missing?

Upvotes: 6

Views: 13497

Answers (3)

Matteo
Matteo

Reputation: 39390

You can specify which method you want to mock (instead of the full class) so the behaviour of the class, so muck only the method you want to test as follow:

public function testFindOne()
{
    $invoice = new Invoice();
    $invoiceRepository = $this
        ->getMockBuilder('\Doctrine\ORM\EntityRepository')
        ->setMethods(array('findOneByNextNote'))
        ->disableOriginalConstructor()
        ->getMock();
    $invoiceRepository->expects($this->once())
        ->method('findOneByNextNote')
        ->will($this->returnValue($invoice));

    $invoiceRepository->findOneByNextNote();
}

So the assertion work as expected

Hope this helps

Upvotes: 4

George Novik
George Novik

Reputation: 163

Sometimes this misunderstanding appear when you call the method before "expects()" instructions. So the code looks great but didn't work.

Example bad:

    $mock = $this
        ->getMockBuilder(YourClass::class)
        ->setMethods(['emit'])
        ->getMock();

    $mock->emit();
    $mock->expects($this->once())->method('emit');

    //Method was expected to be called 1 times, actually called 0 times.

Example good:

    $mock = $this
        ->getMockBuilder(YourClass::class)
        ->setMethods(['emit'])
        ->getMock();

    $mock->expects($this->once())->method('emit');
    $mock->emit();

Upvotes: 9

Gerry
Gerry

Reputation: 6012

Your assertion fails because the EntityRepository does in fact not have an implemented method named findOneByNextNote, and therefore it is also never called.

However, the magic __call method is implemented (and calling findOneByNextNote will be delegated to that method by the PHP engine's method overloading), so you could assert that this method is called to fix your assertion.

A probably better solution would be to actually write a concrete InvoiceRepository class (and I'd suggest even an interface) with that particular method, and mock this class or interface instead.

Upvotes: 2

Related Questions