use*_*816 35 phpunit unit-testing mocking type-hinting symfony
假设我有一个类包含一个使用类型提示的函数,如下所示:
class Testable
{
function foo (Dependency $dependency)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我想Testable使用以下代码对此类进行单元测试:
$dependencyMock = $this->getMockBuilder('Dependency')
->disableOriginalConstructor()
->getMock();
$testable = new Testable($dependencyMock);
Run Code Online (Sandbox Code Playgroud)
如果我使用PHPUnit创建$ dependency的存根,然后尝试foo使用这个模拟调用函数(如上所述),我将得到一个致命的错误,说:
传递给函数foo()的参数1必须是Dependency的一个实例,给出Mock_Foo的实例
如何使用PHPUnit和仍然存根来对此函数进行单元测试$dependency?
Sha*_*kil 43
使用模拟时使用完整命名空间,它将修复嘲弄继承问题.
$dependencyMock = $this->getMockBuilder('\Some\Name\Space\Dependency')
->disableOriginalConstructor()
->getMock();
$testable = new Testable($dependencyMock);
Run Code Online (Sandbox Code Playgroud)
Gaz*_*dge 19
在PHP 5.5+中使用完整命名空间的最简单方法是使用类静态方法:
SomeClass::class
Run Code Online (Sandbox Code Playgroud)
所以在OP的例子中:
$dependencyMock = $this->getMockBuilder(Dependency::class)
->disableOriginalConstructor()
->getMock();
$testable = new Testable($dependencyMock);
Run Code Online (Sandbox Code Playgroud)
这使得使用IDE进行重构变得更加容易
我对Shakil答案的解释是:
我有同样的问题.
在symfony2食谱之后,我创建了一个模拟器
\Doctrine\Common\Persistence\ObjectManager
Run Code Online (Sandbox Code Playgroud)
我的服务构造函数是:
use Doctrine\ORM\EntityManager;
/* ... */
public function __construct(EntityManager $oEm)
{
$this->oEm = $oEm;
}
Run Code Online (Sandbox Code Playgroud)
所以我创建了我的单元测试(在symfony2 cookbook之后):
$entityManager = $this->getMockBuilder('\Doctrine\Common\Persistence\ObjectManager')
->disableOriginalConstructor()
->getMock();
$myService = new MyService($entityManager);
Run Code Online (Sandbox Code Playgroud)
然后我有错误:
Argument 1 passed to MyService::__construct() must be an instance of Doctrine\ORM\EntityManager, instance of Mock_ObjectManager_f4068b7f given
Run Code Online (Sandbox Code Playgroud)
首先,我认为类型提示与单元测试不兼容,因为模拟实例被传递给构造函数而不是EntityManager的实例.
所以在经过一些研究之后,类Mock_ObjectManager_f4068b7f实际上是一个动态类,它扩展了mock的类(在我的例子中是Doctrine\ORM\EntityManager),所以类型提示不是问题而且效果很好.
我的解决方案是创建一个Doctrine\ORM\EntityManager而不是\ Doctrine\Common\Persistence\ObjectManager的模拟:
$entityManager = $this->getMockBuilder('\Doctrine\ORM\EntityManager')
->disableOriginalConstructor()
->getMock();
$myService = new MyService($entityManager);
Run Code Online (Sandbox Code Playgroud)
我刚开始进行单元测试,所以你可能会发现我的解释明显:p
| 归档时间: |
|
| 查看次数: |
10949 次 |
| 最近记录: |