Служба Symfony Unit test с mocks не находит имя класса - PullRequest
0 голосов
/ 07 сентября 2018

Я пытаюсь протестировать на чистом модульном тесте мою службу Symfony (находится в src/AppBundle/Services/CapthaServiceAdapter):

namespace AppBundle\Services;

use AppBundle\Interfaces\CapthaBuilderInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Gregwar\Captcha\CaptchaBuilder;

/**
* The following class is an adapter for Gregwar Captcha Builder
* I do not set Gregwar's Captha Builder as a Service
* Because I want to stay hidden fromt he service container.
*/
class CapthaServiceAdapter implements CapthaBuilderInterface
{

  const IMAGE_INLINE=0;
  const IMAGE_NORMAL=1;

  /**
  * @var Session;
  */
  private $session=null;

  /**
  * @var CaptchaBuilder
  */
  private $capthaBuilder=null;

  public function __construct(Session $sessionManager)
  {
    $this->session=$sessionManager;
    $this->capthaBuilder=new CaptchaBuilder();
  }

  /**
  * @inheritdoc
  * @throws \InvalidArgumentException when type is not either self::IMAGE_INLINE or self::IMAGE_NORMAL
  */
  public function build($identifier,$type)
  {
    if($type!==self::IMAGE_INLINE || $type!==IMAGE_NORMAL){
      throw new \InvalidArgumentException("Type should be either CapthaService::IMAGE_INLINE or CapthaService::IMAGE_NORMAL you provided the value: ".$type);
    }

    $this->builder->build();
    $this->session->set($sessionKey,$this->builder->getPhrase());

    if($type==self::IMAGE_INLINE){
      return $this->builder->inline();
    }

    return $this->builder->output();
  }

  /**
  * @inheritdoc
  */
  public function verify($identifier,$value)
  {
    $capthaSessionValue=$session->get($identifier);
    return $capthaSessionValue && $value===$capthaSessionValue;
  }

}

Итак, я выполнил следующий тестовый пример (расположен в tests/AppBundle/Services/CapthcaServiceTest.php):

namespace Tests\AppBundle\Services;

use PHPUnit\Framework\TestCase;
use AppBundle\Services\CapthaServiceAdapter;
use Symfony\Component\HttpFoundation\Session\Session;


class CapthcaServiceTest extends TestCase
{

  private function getServiceForBuild()
  {
    $mock=$this->createMock(Session::class);
    return new CapthaServiceAdapter($mock);
  }

  public function testBuildInline()
  {
    $service=$this->getServiceForBuild();
    $capthaValue=$service->build('somevalue',CapthaService::IMAGE_INLINE);

     $this->assertRegExp('/^data:image\/jpeg;base64,(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)$/i',$element);
  }
}

Но когда я пытаюсь запустить его, я получаю следующую ошибку:

Ошибка: класс 'AppBundle \ Services \ CapthaServiceAdapter' не найден

Так, как я могу сделать свой тест для поиска моего класса?

Также мой pgpunit.xml содержит следующее содержание:

<?xml version="1.0" encoding="UTF-8"?>

<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
         backupGlobals="false"
         colors="true"
         bootstrap="vendor/autoload.php"
>
    <php>
        <ini name="error_reporting" value="-1" />
        <server name="KERNEL_CLASS" value="AppKernel" />
    </php>

    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>tests</directory>
            <exclude>./tests/Appbundle/Controller/DefaultControllerTest.php</exclude>
        </testsuite>
    </testsuites>

    <filter>
        <whitelist>
            <directory>src</directory>
            <exclude>
                <directory>src/*Bundle/Resources</directory>
                <directory>src/*/*Bundle/Resources</directory>
                <directory>src/*/Bundle/*Bundle/Resources</directory>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

Редактировать 1

Внося изменения, указанные в комментариях (обновил код выше), я получаю сообщение об ошибке:

Ошибка: класс 'Tests \ AppBundle \ Services \ CapthaService' не найден

Вы знаете, как я могу это исправить?

Редактировать 2:

Я также видел этот ответ , поэтому я также публикую свой composer.json:

{
    "name": "pcmagas/ellakcy_member_app",
    "license": "AGPL-v3",
    "type": "project",
    "autoload": {
        "psr-4": {
            "AppBundle\\": "src/AppBundle"
        },
        "classmap": [
            "app/AppKernel.php",
            "app/AppCache.php"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        },
        "files": [
            "vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
        ]
    },
    "require": {
        "php": ">=5.5.9",
        "captcha-com/symfony-captcha-bundle": "4.*",
        "doctrine/doctrine-bundle": "^1.6",
        "doctrine/orm": "^2.5",
        "dunglas/angular-csrf-bundle": "^1.1",
        "gregwar/captcha": "^1.1",
        "sensio/distribution-bundle": "^5.0.19",
        "sensio/framework-extra-bundle": "^5.0.0",
        "symfony/dom-crawler": "^4.1",
        "symfony/monolog-bundle": "^3.1.0",
        "symfony/polyfill-apcu": "^1.0",
        "symfony/swiftmailer-bundle": "^2.6.4",
        "symfony/symfony": "3.4.*",
        "symfony/templating": "^3.4",
        "symfony/twig-bundle": "^4.1",
        "twig/twig": "^1.0||^2.0"
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.0",
        "felixfbecker/language-server": "^5.4",
        "jetbrains/phpstorm-stubs": "dev-master",
        "phpunit/phpunit": "^6.5",
        "sensio/generator-bundle": "^3.0",
        "symfony/phpunit-bridge": "^4.1"
    },
    "scripts": {
        "symfony-scripts": [
            "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
        ],
        "post-install-cmd": [
            "@symfony-scripts"
        ],
        "post-update-cmd": [
            "@symfony-scripts"
        ]
    },
    "config": {
        "sort-packages": true
    },
    "extra": {
        "symfony-app-dir": "app",
        "symfony-bin-dir": "bin",
        "symfony-var-dir": "var",
        "symfony-web-dir": "web",
        "symfony-tests-dir": "tests",
        "symfony-assets-install": "relative",
        "branch-alias": null
    }
}

Как вы видите, он также имеет класс автозагрузки:

"autoload": {
            "psr-4": {
                "AppBundle\\": "src/AppBundle"
            },
            "classmap": [
                "app/AppKernel.php",
                "app/AppCache.php"
            ]
        },
        "autoload-dev": {
            "psr-4": {
                "Tests\\": "tests/"
            },
            "files": [
                "vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
            ]
        },

Также, перейдя в это:

"autoload": {
        "psr-4": {
            "AppBundle\\": "src/AppBundle",
            "AppBundle\\Services":"src/AppBundle/Services",
        },
        "classmap": [
            "app/AppKernel.php",
            "app/AppCache.php"
        ]
    },

Результат к этой ошибке:

Ошибка: класс 'Tests \ AppBundle \ Services \ CapthaService' не найден

Разве я могу заставить phphunit заглядывать в соответствующее пространство имен?

1 Ответ

0 голосов
/ 10 сентября 2018

Над вашим кодом есть строка, которая упоминает:

$capthaValue=$service->build('somevalue',CapthaService::IMAGE_INLINE);

Класс CapthaService где определяется? Вы имели в виду CapthaServiceAdapter (возможно, остаток от рефактора?)

Изменитесь на это, и это должно быть хорошо.

...