Fed*_*ddu 2 php phpunit composer-php
当我尝试测试这个类时,使用PSR-4自动加载Composer:
namespace User;
use User\Contracts\UserId;
use User\Contracts\User as UserContract;
class User implements UserContract
{
private $id;
public function __construct(UserId $id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
}
Run Code Online (Sandbox Code Playgroud)
使用PHPUnit:
use User\Contracts\UserId;
class UserTest extends \PHPUnit_Framework_TestCase
{
public function test_the_identifier_can_be_used_as_string()
{
$identifier = m::mock(UserId::class);
$identifier->shouldReceive('__toString')->once()->andReturn('foo');
$user = new User($identifier);
$this->assertSame('foo', (string) $user->getId());
}
}
Run Code Online (Sandbox Code Playgroud)
我在控制台中收到此错误
PHP Fatal error: Cannot use User\Contracts\UserId as UserId because the name is already in use in /src/User/User.php on line 5
Run Code Online (Sandbox Code Playgroud)
这是文件/文件夹结构:
src
`-- User
|-- Contracts
| |-- User.php
| `-- UserId.php
|-- User.php
`-- UserId.php
tests
`-- User
|-- UserIdTest.php
`-- UserTest.php
Run Code Online (Sandbox Code Playgroud)
我已经对这些问题进行了大量搜索,但我没有找到任何解决方案.
我怎么解决这个问题?
您不能将类导入已使用相同别名在其中声明的命名空间.
你必须\User\UserId和要导入\User\Contracts\UserId到\User命名空间.这会使捷径UserId变得模糊.
http://php.net/manual/en/language.namespaces.importing.php#117334
您可以在导入时使用别名,也可以直接使用相对路径:
namespace User;
class User implements Contracts\User
{
private $id;
public function __construct(Contracts\UserId $id) {}
}
Run Code Online (Sandbox Code Playgroud)
更新2018-03-20:
有一个错误报告https://bugs.php.net/bug.php?id=66773,如果在没有操作码缓存的情况下使用,则会抱怨PHP触发此错误,但不是.原因是使用opcache编译是按文件完成的,并且合理的期望是仅考虑文件的内容.但是,似乎错误是以前加载的文件中的现有类定义在导入"冲突"类时会受到影响.
它以正确的方式修复了PHP 7.0.13:每个文件只能自己编写,如果你想导入一个类并按照它的简写名称使用它,你可以这样做而不管其中可能存在的任何其他类.命名空间.您只是松开了对这些类的访问 - 这是无关紧要的,因为您的代码首先不使用它们.如果您想要更改,则必须更改导入.
由于opcache通常在命令行上被禁用,因此在使用PHPUnit时可能会触发此错误.