Unit testing 如何对使用类型暗示的函数进行单元测试

Unit testing 如何对使用类型暗示的函数进行单元测试,unit-testing,symfony,mocking,phpunit,type-hinting,Unit Testing,Symfony,Mocking,Phpunit,Type Hinting,假设我有一个类,它包含一个使用类型暗示的函数,如下所示: class Testable { function foo (Dependency $dependency) { } } 我想使用以下代码对这个类进行单元测试Testable: $dependencyMock = $this->getMockBuilder('Dependency') ->disableOriginalConstructor() ->getM

假设我有一个类,它包含一个使用类型暗示的函数,如下所示:

class Testable 
{
    function foo (Dependency $dependency) 
    {

    }
}
我想使用以下代码对这个类进行单元测试
Testable

$dependencyMock = $this->getMockBuilder('Dependency')
        ->disableOriginalConstructor()
        ->getMock();


$testable = new Testable($dependencyMock);
如果我使用PHPUnit创建一个$dependency存根,然后尝试使用这个mock调用函数
foo
(如上所述),我将得到一个致命错误,该错误表示:

传递给函数foo()的参数1必须是Dependency的实例,Mock_foo的实例已给定


如何使用PHPUnit和stub对该函数进行单元测试
$dependency

使用mocking时使用完整名称空间,它将修复mockry继承问题

$dependencyMock = $this->getMockBuilder('\Some\Name\Space\Dependency')
    ->disableOriginalConstructor()
    ->getMock();
$testable = new Testable($dependencyMock);

我对颤抖者回答的解释是:

我也有同样的问题

根据symfony2食谱,我创建了一个

\Doctrine\Common\Persistence\ObjectManager
我的服务构造函数是:

use Doctrine\ORM\EntityManager;

/* ... */

public function __construct(EntityManager $oEm)
{
    $this->oEm = $oEm;
}
因此,我创建了我的单元测试(遵循symfony2食谱):

然后我犯了一个错误:

Argument 1 passed to MyService::__construct() must be an instance of Doctrine\ORM\EntityManager, instance of Mock_ObjectManager_f4068b7f given
首先,我认为类型暗示与单元测试不兼容,因为模拟实例被传递给构造函数,而不是EntityManager的实例

因此,经过一些研究后,类Mock\u ObjectManager\u f4068b7f实际上是一个动态类,它扩展了Mock的类(在我的例子中是Doctrine\ORM\EntityManager),因此类型暗示不是一个问题,并且工作良好

我的解决方案是创建一个模拟的条令\ORM\EntityManager,而不是\doctor\Common\Persistence\ObjectManager

$entityManager = $this->getMockBuilder('\Doctrine\ORM\EntityManager')
    ->disableOriginalConstructor()
    ->getMock();

$myService = new MyService($entityManager);

我刚刚开始单元测试,因此您可能会发现我的解释很明显:在PHP 5.4+中使用完整名称空间的最简单方法是使用类静态方法:

SomeClass::class
在OP的例子中:

$dependencyMock = $this->getMockBuilder(Dependency::class)
    ->disableOriginalConstructor()
    ->getMock();
$testable = new Testable($dependencyMock);

这使得使用IDE进行重构更加容易

在创建模拟的位置显示测试代码。您确定
依赖项
是一个存在的类吗?它不应该有一个名称空间吗?尝试使用完整的名称空间,如\some\name\space\Dependency当您使用mocking时,它应该会修复,谢谢!使用名称空间修复了错误。@Shakil您应该将注释移动到一个答案,这样它可能会被接受。这比其他答案(在PHP 5.4+中)要好<代码>::class是确保使用正确的类的方法。我终于找到了答案。谢谢!谢谢你。我认为您需要完整名称空间的事实在文档中并不清楚。当我看到你的帖子时,我想“哦!当然”,但我并没有从文档中了解到这一点+
$dependencyMock = $this->getMockBuilder(Dependency::class)
    ->disableOriginalConstructor()
    ->getMock();
$testable = new Testable($dependencyMock);