首页 > 解决方案 > 了解 PHPUnit 中的导入/使用

问题描述

在 PHPUnit 测试中,我试图让我的 symfony 应用程序的所有类都实现了某个接口。我的应用程序代码位于命名空间中App,我的测试位于Tests.

如果我实例化(或“使用”)它(use顶部的语句无效) ,则此 TestCase 代码仅列出一个类:

namespace Tests\ReportPlaceholder;

use App\ReportPlaceholder\LimitModificationsPlaceholder;
use App\ReportPlaceholder\SimpleEvaluatePlaceholder;
use App\ReportPlaceholder\ReportPlaceholderInterface;

class MyTest extends KernelTestCase{


    public function provider(){

        new SimpleEvaluatePlaceholder(); // <-- if I comment this line, the class is *not* found
        // also a usage of SimpleEvaluatePlaceholder::class suffices

        return array_map(function($p) { return [$p]; }, 
                array_filter(get_declared_classes(), function($className){
                     return in_array(ReportPlaceholderInterface::class, class_implements($className));}
        ));
    }
}

provider仅在这种情况下返回SimpleEvaluatePlaceholder

我的 composer.json 是

"autoload": {
    "psr-4": {
        "App\\": "src/"
    }
},
"autoload-dev": {
    "psr-4": {
        "Tests\\": "tests/"
    }
},

和 phpunit.xml 读取:

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.5/phpunit.xsd"
     backupGlobals="false"
     colors="true"
     bootstrap="config/bootstrap.php"
     verbose="true"
     debug="false"
     stopOnFailure="true">

标签: phpsymfonyphpunit

解决方案


由于您使用的是 Container,因此您可以访问 Container,您可以通过以下方式(Symfony 3.4 或更高版本)KernelTestCase标记所有实现您的接口的服务并将它们传递给 Registry 服务来轻松实现它:

# services.yml
services:
  _instanceof:
    YourInterface:
      tags: ['my_custom_tag']

  App\Registry\MyCustomTagRegistry:
    arguments: [!tagged my_custom_tag]

您的注册表类:

class MyCustomTagRegistry
{
  /** @var Traversable */
  private $services;

  public function __construct(iterable $services = [])
  {
    $this->services = $services;
  }

  public function getServices(): array
  {
    return (array) $this->services;
  }
}

然后在您的测试中,您需要从容器中获取给定的服务:

$services = self::$container->get(MyCustomTagRegistry::class)->getServices();

您可以在此处找到有关如何使用服务标签的更多详细信息:


推荐阅读