我正在尝试为一个受保护的方法编写一个单元测试,我知道我可以使用反射类来实现这一点。问题是,这个受保护的方法调用了两个私有方法,我需要模拟这些私有方法(我有我的原因)。这甚至可能吗?
下面是我的课堂:
class MyClass
{
protected function myProtectedMethod(string $argOne, int $argTwo)
{
$privateMethodOneValue = $this->privateMethodOne($argOne);
$privateMethodTwoValue = $this->privateMethodTwo($argTwo);
// Some more logic below that is unrelated to the question
}
private function privateMethodOne(string $arg): string
{
// does some laravel specific stuff that can't be unit tested in PHPUnit\Framework\TestCase
// this is why it was abstracted out from the protected method, to make unit testing possible
}
private function privateMethodTwo(int $arg): int
{
// does some laravel specific stuff that can't be unit tested in PHPUnit\Framework\TestCase
// this is why it was abstracted out from the protected method, to make unit testing possible
}
}
在我的测试中,我得到了这样的结果:
use PHPUnit\Framework\TestCase;
class MyClassTest extends TestCase
{
public function testMyProtectedMethod()
{
$mmyMockClass = $this->getMockBuilder(Controller::class)
->onlyMethods(['privateMethodOne', 'privateMethodTwo'])
->getMock();
$reflectionClass = new \ReflectionClass($mmyMockClass);
$privateMethodOne = $reflectionClass->getMethod('privateMethodOne');
$privateMethodOne->setAccessible(true);
$privateMethodTwo = $reflectionClass->getMethod('privateMethodTwo');
$privateMethodTwo->setAccessible(true);
$myProtectedMethod = $reflectionClass->getMethod('myProtectedMethod');
$myProtectedMethod->setAccessible(true);
$mockArgOne = 'some argument string';
$mockArgTwo = 99999;
$privateMethodOneResult = 'some result string';
$privateMethodTwoResult = 88888;
$mmyMockClass->expects($this->once())
->method('privateMethodOne')
->with($mockArgOne)
->willReturn($privateMethodOneResult);
$mmyMockClass->expects($this->once())
->method('privateMethodTwo')
->with($mockArgTwo)
->willReturn($privateMethodTwoResult);
$result = $myProtectedMethod->invoke($reflectionClass, $mockArgOne, $mockArgTwo);
// some assertions here
}
}
但显然这不起作用。我尝试模拟的私有方法出现错误。错误如下所示:第一个月
我已经读了很多关于这个的文章和帖子,我知道通常来说,尝试对私有方法进行单元测试是一个不好的做法,并且/或者如果你发现自己必须测试它,这是一个不好的设计。我理解所有这些,如果有更多关于这方面的内容我需要阅读,那也是受欢迎的,但是,我,至少试图理解这是否是可能的,也很想知道是怎么回事。
先谢谢大家。
1条答案
按热度按时间slwdgvem1#
第一个月
应该是
$result = $myProtectedMethod->invoke($mmyMockClass, $mockArgOne, $mockArgTwo);
有关如何使用“invoke”方法的详细信息,请单击此处。https://www.php.net/manual/en/reflectionmethod.invoke.php