【问题标题】:Is it possible to mock protected properties and methods是否可以模拟受保护的属性和方法
【发布时间】:2015-11-05 20:40:28
【问题描述】:

是否可以使用 PHP Mockery 模拟受保护的属性?

我有一个带有方法的类,我将其命名为 `a,它对从同一类的受保护属性中检索到的数组执行一些魔法。

该受保护属性由同一类中的另一个方法 b 填充。

我想通过模拟受保护的属性来测试方法a,这样我就不必首先对方法b 进行分类。

那么这可能吗?如果不是,我应该重构我的代码吗?还是有其他方法(考虑最佳实践)。

【问题讨论】:

  • 尝试使用反射
  • 我(当然)做了谷歌,这确实是第一件事。但这感觉有点“骇人听闻”。我也想知道如何将它与部分模拟混合。
  • 如果感觉很骇人,那么重构你的代码。我不完全确定你想做什么,但反射通常是当你不知道类属性是什么时动态读取它们的方法。
  • 如果您想模拟私有或受保护的方法,而您的代码看起来很糟糕,请尝试重构它。

标签: php mocking phpunit protected mockery


【解决方案1】:

有时你的代码很好,你认为没有理由改变你的代码来促进测试(我认为这是一个很好的理由),我所做的是在我的对象中使用反射,你甚至可以有一个助手方法如下:

class MockingHelpers
{
    public static function mockProperty($object, string $propertyName, $value)
    {
        $reflectionClass = new \ReflectionClass($object);

        $property = $reflectionClass->getProperty($propertyName);
        $property->setAccessible(true);
        $property->setValue($object, $value);
        $property->setAccessible(false);
    }
}

请注意,可访问性仅应用于反射上下文,因此不会造成任何损坏。

这不是完美的解决方案,有时您的代码可能确实存在问题,但这可以帮助您!

【讨论】:

    【解决方案2】:

    可以模拟受保护的方法,但正如一些人指出的那样,如果您觉得需要模拟这些方法,您可能需要重构您的代码。

    如果你确实想模拟受保护的方法,你可以按照下面的例子来做:

    $myMock = Mockery::mock('myClass')->shouldAllowMockingProtectedMethods();
    

    使用这个模拟,就可以像模拟公共方法一样模拟受保护的方法。

    【讨论】:

    • 这种方法适用于受保护的方法,但不适用于受保护的属性
    猜你喜欢
    • 2020-03-31
    • 2012-01-08
    • 2012-11-18
    • 2016-02-19
    • 1970-01-01
    • 2016-03-17
    • 2019-03-03
    • 1970-01-01
    相关资源
    最近更新 更多