【问题标题】:PHPUnit: How to mock private methods? [duplicate]PHPUnit:如何模拟私有方法? [复制]
【发布时间】:2014-12-13 03:12:28
【问题描述】:

我有这样的课:

class A {

    private function testing($x)
    {
        // do something
        $this->privateMethod();
    }

    private function privateMethod($number) {
        // do something
    }

}

调用 testing() 我使用这个:

$reflection = new \ReflectionClass('A');
$method = $reflection->getMethod('testing');
$method->setAccessible(TRUE);

$object = new A();
$parameters = array();
$result = $method->invokeArgs($object, $parameters);

但我不知道如何模拟 privateMethod()。我只想测试 testing() 方法中的代码。我想指出我希望 privateMethod() 在没有实际调用方法的情况下返回结果。

【问题讨论】:

  • 我认为你不需要测试私有方法也不需要模拟一个。你真的应该测试公共方法;其他类将依赖的那些。
  • 单元测试的重点是测试你的公共接口。您的私有方法最终应该在您的代码中的某处被调用,由公共/受保护的方法触发。从理论上讲,如果您的私有方法没有按预期工作,那么调用代码(您正在测试的)将无法工作,因此您所做的任何断言都应该失败。
  • 我的类包括一个公共方法和大约 10 个私有方法。公共方法只是调用了一些私有方法,而工作实际上是由它们完成的。它们中的任何一个的结果都取决于数据库中的数据。如何测试这些方法?
  • 通常你会模拟数据库或提供一个测试数据库来使用。
  • @Crackertastic 如果这些私有/受保护的方法可能会改变测试方法的行为,那么您必须模拟它们以期望某些值来使测试工作,因此私有/受保护的方法将是没有被测试单元覆盖?

标签: php unit-testing phpunit


【解决方案1】:

如果您可以将私有更改为受保护,则可以为此使用部分模拟。

$object = $this->getMockBuilder('A')
    ->setMethods(array('privateMethod'))
    ->getMock();
$object->expects($this->any())
    ->method('privateMethod')
    ->will($this->returnValue($x));

这将仅替换 setMethods 数组中的方法的实现,所有其他方法将执行原始代码。然而,这不适用于私有方法,因为模拟对象扩展了原始方法;但它不能覆盖private

【讨论】:

猜你喜欢
  • 2016-03-21
  • 2011-10-30
  • 2016-01-30
  • 2018-07-17
  • 1970-01-01
  • 2019-08-07
  • 2013-01-27
  • 2013-02-02
  • 2017-03-15
相关资源
最近更新 更多