【问题标题】:Method was expected to be called 1 times, actually called 0 times [PHPUnit]方法预期调用1次,实际调用0次[PHPUnit]
【发布时间】:2015-09-03 13:01:20
【问题描述】:

我一直在测试、添加和删除行以查看问题出在哪里。我已经设法剪掉了这么多行,基本上我的测试看起来像那样(当然要看看有什么问题,我知道这不是正确的测试):

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

还是不行!我从标题中得到一个错误:

方法名称的期望失败等于 调用 1 次时。方法是预期的 调用1次,实际调用0次。

我错过了什么?

【问题讨论】:

  • 我们不知道您遗漏了什么,但我们遗漏了经过测试的代码;)
  • 我不知道你的模拟框架是如何工作的,但是对于其他框架,你必须“开始”你的模拟。喜欢EasyMock.replay(mockObject)
  • @lukelazarovic 但我的测试现在看起来像这样!并且仍然无法正常工作。
  • 我认为问题在于实际上并没有调用名为“findOneByNextNote”的真正方法,因为这是通过方法重载委托给 EntityRepository 的 __call 方法的。

标签: php symfony phpunit


【解决方案1】:

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

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

所以断言按预期工作

希望对你有帮助

【讨论】:

  • 为什么有人在没有任何解释的情况下投了反对票?是针对问题中描述的问题的有效且经过测试的解决方案
  • 我不相信这个解决方案是理想的,你也可以去模拟 stdClass 而不是存储库类。
【解决方案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();

【讨论】:

    【解决方案3】:

    您的断言失败,因为 EntityRepository 实际上没有实现名为 findOneByNextNote 的方法,因此它也从未被调用。

    然而,神奇的__call 方法已实现(调用findOneByNextNote 将被PHP 引擎的方法重载委托给该方法),因此您可以断言调用此方法来修复您的断言。

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

    【讨论】:

      猜你喜欢
      • 2017-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      • 2020-09-15
      • 2021-08-15
      • 2017-07-15
      相关资源
      最近更新 更多