Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 禁用未模拟的类中的方法_Php_Phpunit_Php 7 - Fatal编程技术网

Php 禁用未模拟的类中的方法

Php 禁用未模拟的类中的方法,php,phpunit,php-7,Php,Phpunit,Php 7,我有一个带解析器的简单类 class Parser { public function __construct(P1 $p1, P2 $p2) { $this->p1 = $p1; // etc... } public function parse() { $this->doSomething1(); return $this->doSomething2(P3 $p3);

我有一个带解析器的简单类

class Parser
{
    public function __construct(P1 $p1, P2 $p2)
    {
        $this->p1 = $p1;
        // etc...
    }

    public function parse()
    {
        $this->doSomething1();
        return $this->doSomething2(P3 $p3);
    }
}
然后我有我的测试课

class ParserTest
{
    public function testParse()
    {

      $p1 = $this->getMockBuilder(P1::class)->disableOriginalConstructor()->getMock();
      $p2 = $this->getMockBuilder(P2::class)->disableOriginalConstructor()->getMock();
      $p3 = $this->getMockBuilder(P3::class)->disableOriginalConstructor()->getMock();
     
      $parser = new Parser ($p1, $p2);
      $result = $parser->parse($p3);

    }
}

我需要做的是为测试禁用doSomething1,因为它基本上是在进行API调用,所以我可以测试结果。我该怎么做呢?

正如El_Vanja已经建议的那样,最好提取API调用。如果现在无法执行此操作,则可以覆盖测试的
doSomething1
方法:

class ParserTest
{
    public function testParse()
    {
      $p1 = $this->getMockBuilder(P1::class)->disableOriginalConstructor()->getMock();
      $p2 = $this->getMockBuilder(P2::class)->disableOriginalConstructor()->getMock();
      $p3 = $this->getMockBuilder(P3::class)->disableOriginalConstructor()->getMock();
     
      $parser = new class($p1, $p2) extends Parser {
            protected function doSomething1()
            {
            }
      };

      $result = $parser->parse($p3);
    }
}

您可以使用被测试类的PHPUnit部分模拟(我没有找到有效的文档,只有一些PR或在源代码中),例如:

    $methods = ["doSomething1"];


    $parser = $this->getMockBuilder(Parser::class)
        ->disableOriginalClone()
        ->disableArgumentCloning()
        ->disallowMockingUnknownTypes()
        ->onlyMethods($methods)
        ->setConstructorArgs([$p1, $p2])
        ->getMock();
注意:因为您需要在构造函数中传递数据,所以不能使用short cat版本:

    $this->createPartialMock(Parser::class, $methods);

这是您需要重构代码的标志。解析器不应该通过API获取数据,它应该只解析给定的数据。明智的做法是将抓取提取到一个单独的服务类,并将其结果作为参数传递给
parse
方法。是的,我怀疑我必须这样做,我只是在想有没有更快的方法。无论如何,谢谢。哪个可见性有
doSomething1
方法?也许你可以用一个局部模拟。。。