【问题标题】:Argument 1 passed to Foo::__construct() must be an instance of Psr\Log\LoggerTrait, instance of Mock_Trait_LoggerTrait_65811a25_bdddd884 given传递给 Foo::__construct() 的参数 1 必须是 Psr\Log\LoggerTrait 的实例,给定的 Mock_Trait_LoggerTrait_65811a25_bdddd884 的实例
【发布时间】:2015-05-11 03:49:25
【问题描述】:

我正在尝试使用 PHPUnit 模拟一个简单的特征,但它会导致 FatalError,如果我删除类型提示,它会起作用:传递给 Foo::__construct() 的参数 1 必须是 Psr\Log\ 的实例LoggerTrait,Mock_Trait_LoggerTrait_65811a25_bdddd884 的实例给定

班级:

use Psr\Log\LoggerTrait;

class Foo {

    /**
     * @var LoggerTrait
    */
    private $mLogger;

    public function __construct(LoggerTrait $iLogger)
    {
        $this->mLogger = $iLogger;
    }
}

测试:

class FooTest extends \PHPUnit_Framework_TestCase
{
    public function testRun ()
    {
        $logger = $this->getMockForTrait('\Psr\Log\LoggerTrait');

        $sut = new Foo($logger);
    }
}

我应该如何解决这个问题?

【问题讨论】:

  • 我应该如何解决这个问题?LoggerTrait 类中的实例传递给构造函数?!
  • 我发现它也很棘手。如果你做一个 var_dump($logger);在你 getMockForTrait 之后,它是“LoggerTrait”类型的对象吗?您绝对不想删除您的类型提示。那会很糟糕。我解决这个问题的一种方法是在测试助手中创建一个存根 Trait,然后将其提供给 getMockForTrait。很烂,但有效。

标签: php unit-testing mocking phpunit traits


【解决方案1】:

您不能输入提示特征。您的类型提示正在寻找\Psr\Log\LoggerTrait 类型的类。看起来它实际上是一个特征而不是一个对象。

http://php.net/manual/en/language.oop5.typehinting.php

getMockForTrait 方法用于创建特征的具体对象,以便您可以测试特征功能。它创建一个对象,该对象使用特征方法和任何被模拟的抽象方法。它没有扩展 trait,所以类型提示无效。

https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.mocking-traits-and-abstract-classes

您似乎在将特征滥用于您想要做的事情。 trait 是 PHP 允许类共享功能而无需相互扩展的方式。无法实例化特征,它们将用于在其他不相关的对象之间共享功能。

你的“特质”应该只是你传入的一个类。然后你的测试将变成:

public function testRun ()
{
    $logger = $this->getMock('\Psr\Log\Logger');  //Changed name to not be Trait

    $sut = new Foo($logger);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-15
    • 2017-04-06
    • 2017-06-12
    • 1970-01-01
    • 2018-08-30
    • 2018-08-14
    • 1970-01-01
    • 2020-06-15
    相关资源
    最近更新 更多