laravel PHPUnit测试受保护的方法,该方法调用需要模拟的私有方法

amrnrhlw  于 2022-12-30  发布在  PHP
关注(0)|答案(1)|浏览(185)

我正在尝试为一个受保护的方法编写一个单元测试,我知道我可以使用反射类来实现这一点。问题是,这个受保护的方法调用了两个私有方法,我需要模拟这些私有方法(我有我的原因)。这甚至可能吗?
下面是我的课堂:

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
    }
}

但显然这不起作用。我尝试模拟的私有方法出现错误。错误如下所示:第一个月
我已经读了很多关于这个的文章和帖子,我知道通常来说,尝试对私有方法进行单元测试是一个不好的做法,并且/或者如果你发现自己必须测试它,这是一个不好的设计。我理解所有这些,如果有更多关于这方面的内容我需要阅读,那也是受欢迎的,但是,我,至少试图理解这是否是可能的,也很想知道是怎么回事。
先谢谢大家。

slwdgvem

slwdgvem1#

第一个月
应该是
$result = $myProtectedMethod->invoke($mmyMockClass, $mockArgOne, $mockArgTwo);
有关如何使用“invoke”方法的详细信息,请单击此处。https://www.php.net/manual/en/reflectionmethod.invoke.php

相关问题