【发布时间】:2016-01-03 16:10:59
【问题描述】:
我正在构建一个需要直接访问 Composer 的 PHP 应用程序。然而,为了测试应用程序,我实际上并不想运行 composer,所以我试图模拟它。
<?php
namespace MyNamespace;
use Composer\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
class MyTest extends \PHPUnit_Framework_TestCase {
public function testComposer()
{
/** @var Application|\PHPUnit_Framework_MockObject_MockObject $composer */
$composer = $this->getMockForAbstractClass(Application::class);
$composer
->expects($this->any())
->method('run')
->will($this->returnValue(true));
$this->assertTrue(
$composer->run(new ArrayInput(['command' => 'install']))
);
}
}
这实际上是运行代码:
$ bin/phpunit -c phpunit-fast.xml tests/MyTest.php
PHPUnit 4.8.10 by Sebastian Bergmann and contributors.
Runtime: PHP 5.6.13-1+deb.sury.org~trusty+3 with Xdebug 2.3.2
Configuration: phpunit-fast.xml
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Nothing to install or update
Generating autoload files
我尝试了->getMock(完全失败)和->getMockBuilder 的各种组合,但它似乎总是实际使用->run 方法而不是存根。
我认为它以某种方式替换了这些方法本身,但如果是这种情况,我该如何防止它?
更新
有人问我为什么使用getMockForAbstractClass 而不仅仅是getMock。使用getMock 时,我得到以下输出:
PHPUnit 4.8.10 by Sebastian Bergmann and contributors.
Runtime: PHP 5.6.13-1+deb.sury.org~trusty+3 with Xdebug 2.3.2
Configuration: phpunit.xml.dist
E
Time: 1.19 minutes, Memory: 4.50Mb
There was 1 error:
1) MyNamespace\MyTest::testComposer
PHPUnit_Framework_MockObject_RuntimeException: Cannot mock Symfony\Component\Console\Application::setDispatcher() because a class or interface used in the signature is not loaded
tests/MyTest.php:22
Caused by
ReflectionException: Class Symfony\Component\EventDispatcher\EventDispatcherInterface does not exist
tests/MyTest.php:22
FAILURES!
Tests: 1, Assertions: 0, Errors: 1.
尽管使用$composer = new Application(); 可以正常工作。事实上,如果我在测试上方添加该行,它仍然声称没有加载 class or interface,尽管该对象之前已正确实例化。
【问题讨论】:
-
作曲家
Application类不是抽象类。那你为什么用getMockForAbstractClass()呢? -
好问题,我会更新上面的信息说明原因。 :)
-
当我这样做时它对我有用: $composer = $this->getMock('\Composer\Console\Application');显示 Application::class 时会得到什么?
-
当我回显
Application::class时,我确实得到了Composer\Console\Application。按照建议尝试$composer = $this->getMock('\Composer\Console\Application');会导致与上述相同的错误。 -
@Bang 你用的是什么版本的包?
标签: php mocking phpunit composer-php