Php Foo类中的方法栏使用调试方法记录消息。如何为方法栏编写测试代码

Php Foo类中的方法栏使用调试方法记录消息。如何为方法栏编写测试代码,php,phpunit,Php,Phpunit,我的类Foo有一个名为Bar的方法,调用该方法时会记录调试消息。类Foo在其_构造方法中获取\Psr\Log\LoggerInterface$logger。我已经在我的FooTest类中创建了一个testBar方法,但是我的Bar方法中的调试方法给出了以下错误 PHP致命错误:类Mock_LoggerInterface_a49cf619包含8个抽象>方法,因此必须声明为抽象或实现其余>方法(Psr\Log\LoggerInterface::emergency,Psr\LoggerInterfac

我的类Foo有一个名为Bar的方法,调用该方法时会记录调试消息。类Foo在其_构造方法中获取\Psr\Log\LoggerInterface$logger。我已经在我的FooTest类中创建了一个testBar方法,但是我的Bar方法中的调试方法给出了以下错误

PHP致命错误:类Mock_LoggerInterface_a49cf619包含8个抽象>方法,因此必须声明为抽象或实现其余>方法(Psr\Log\LoggerInterface::emergency,Psr\LoggerInterface>\LoggerInterface::alert,Psr\Log\LoggerInterface::critical,…)在/var/www/html/myproject/vendor/phpunit/phpunit mock objects>/src/Generator.php(264):eval()'d第1行的代码中

我的班级代码如下

use Psr\Log\LoggerInterface;

class Foo {


    private $logger;
    private $myclassObject;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }
    public function Bar ()
    {
      // some code
      $logger->debug ('debug message')

    }
}
use PHPUnit\Framework\TestCase;

class FooTest extends TestCase
{

    private $logger;
    public function setUp()
    {
        $this->logger = $this->getMockBuilder('\Psr\Log\LoggerInterface')
            ->setMethods(null)
            ->getMock();

        $this->logger->expects($this->any())
            ->method('debug')
            ->willReturn('Message Logged');
    }

    $this->myclassObject = $this->getMockBuilder('MyVendor\MyModule\Model\Foo')
    ->setMethods(['__construct'])        
    ->setConstructorArgs(['$logger'])
    ->disableOriginalConstructor()
    ->getMock();

    public function testBar()
    {

        $this->assertEquals($expected_result,$this->myclassObject->Bar());
    }
}

下面是我的测试课

use Psr\Log\LoggerInterface;

class Foo {


    private $logger;
    private $myclassObject;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }
    public function Bar ()
    {
      // some code
      $logger->debug ('debug message')

    }
}
use PHPUnit\Framework\TestCase;

class FooTest extends TestCase
{

    private $logger;
    public function setUp()
    {
        $this->logger = $this->getMockBuilder('\Psr\Log\LoggerInterface')
            ->setMethods(null)
            ->getMock();

        $this->logger->expects($this->any())
            ->method('debug')
            ->willReturn('Message Logged');
    }

    $this->myclassObject = $this->getMockBuilder('MyVendor\MyModule\Model\Foo')
    ->setMethods(['__construct'])        
    ->setConstructorArgs(['$logger'])
    ->disableOriginalConstructor()
    ->getMock();

    public function testBar()
    {

        $this->assertEquals($expected_result,$this->myclassObject->Bar());
    }
}


我希望看到一个成功的单元测试,使用存根调试方法记录“messagelogged”

我忽略了在类级别定义
$this->myclassObject
的语法问题,因为我假设这是您创建此问题时的一个输入错误

我认为你有两个问题:

  • 通过在LoggerInterface的setMethods中指定
    null
    ,您正在覆盖PHPUnit模拟类/接口的抽象/接口方法的能力,这告诉它不要模拟任何东西
  • 您正在禁用Foo构造函数并提供构造函数args(在引号中作为变量名的标量值)
您还引用了不存在的
$logger

我还建议,在您的示例中,您根本不需要部分模拟Foo,因为此时您没有模拟它的任何功能。您只需调用
newfoo($this->logger)
。然而,我假设您的示例已被缩减,并且您确实需要部分模拟类的其他部分,所以现在就不讨论了

试试这个:

class FooTest扩展了TestCase
{
私人电脑;
私有$myclassObject;
受保护的函数设置()
{
$this->logger=$this->createMock('\Psr\Log\LoggerInterface');
$this->logger->expected($this->any())
->方法('debug')
->willReturn(‘记录消息’);
$this->myclassObject=$this->getMockBuilder('\MyVendor\MyModule\Model\Foo'))
->setConstructorArgs([$this->logger])
->getMock();
}
公共函数testBar()
{
$this->assertEquals($expected_result,$this->myclassObject->Bar());
}
}

感谢myclassObject的更正。在我看来,我认为在foomock中需要使用disableOriginalConstructor,因为我们正在使用stubing记录器调试方法。此外,此“已记录消息”将保存在何处。如果它保存在这里,我在debug.log中找不到它。您正在模拟记录器,因此它不会在任何地方记录。您可以运行断言,在您的mock上调用它