是否可以模拟受保护的属性和方法
Posted
技术标签:
【中文标题】是否可以模拟受保护的属性和方法【英文标题】:Is it possible to mock protected properties and methods 【发布时间】:2015-11-05 20:40:28 【问题描述】:是否可以使用 php Mockery 模拟受保护的属性?
我有一个带有方法的类,我将其命名为 `a,它对从同一类的受保护属性中检索到的数组执行一些魔法。
该受保护属性由同一类中的另一个方法 b
填充。
我想通过模拟受保护的属性来测试方法a
,这样我就不必首先对方法b
进行分类。
那么这可能吗?如果不是,我应该重构我的代码吗?还是有其他方法(考虑最佳实践)。
【问题讨论】:
尝试使用反射 我(当然)做了谷歌,这确实是第一件事。但这感觉有点“骇人听闻”。我也想知道如何将它与部分模拟混合。 如果感觉很骇人,那么重构你的代码。我不完全确定你想做什么,但反射通常是当你不知道类属性是什么时动态读取它们的方法。 如果您想模拟私有或受保护的方法,而您的代码看起来很糟糕,请尝试重构它。 phpunit - mockbuilder - set mock object internal property的可能重复 【参考方案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();
使用这个模拟,就可以像模拟公共方法一样模拟受保护的方法。
【讨论】:
这种方法适用于受保护的方法,但不适用于受保护的属性以上是关于是否可以模拟受保护的属性和方法的主要内容,如果未能解决你的问题,请参考以下文章