预计方法被调用1次,实际上被称为0次[PHPUnit]

时间:2015-09-03 13:01:21

标签: php symfony phpunit

我一直在测试,添加和删除行以查看问题所在。我设法削减了很多行,基本上我的测试看起来就像那样(当然要看错了,我知道这不是正确的测试):

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();
}

仍然无法运作!我从标题中收到错误:

  

方法名称的期望失败等于   < string:findOneByNextNote>当被调用1次时。方法是预期的   被召唤1次,实际上被称为0次。

我错过了什么?

3 个答案:

答案 0 :(得分:4)

您可以指定要模拟的方法(而不是完整的类)以及类的行为,因此只需要测试您要测试的方法如下:

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

    $invoiceRepository->findOneByNextNote();
}

因此断言按预期工作

希望这个帮助

答案 1 :(得分:2)

您的断言失败,因为EntityRepository实际上没有一个名为findOneByNextNote的已实现方法,因此它也永远不会被调用。

然而,实现了神奇的__call方法(并且调用findOneByNextNote将通过PHP引擎的方法重载委托给该方法),因此您可以声明此方法被调用修复你的断言。

一个可能更好的解决方案是用这个特定方法实际编写一个具体的InvoiceRepository类(我甚至建议一个接口),然后改为模拟这个类或接口。

答案 2 :(得分:2)

有时,当您在“ expects()”指令之前调用该方法时,会出现这种误解。因此,代码看起来不错,但没有用。

示例不好

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

示例

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

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