Ложный сервис в тесте команды symfony4 - PullRequest
0 голосов
/ 04 июля 2018

У меня проблема с командой test. Я пытаюсь смоделировать службу внутри командного теста, но есть проблема, что этот макет не используется в тесте.

Вот код команды:

    public function __construct(RpcClient $rpcClient, LoggerInterface $logger, EntityManagerInterface $entityManager)
{
    $this->rpcClient = $rpcClient;
    $this->logger = $logger;
    $this->entityManager = $entityManager;

    parent::__construct();
}

protected function execute(InputInterface $input, OutputInterface $output)
{
    $apiSecurityKey = $this->getContainer()->getParameter('api_security_key');
    try {
        $apiBoxesData = $this->rpcClient->callJsonRPCPostMethod("stations_info", ["apiSecurityKey" => $apiSecurityKey]); 
.
.
.

И тест:

//some of dependencies used
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Tester\CommandTester;

class SynchronizeBoxInfoCommandTest extends KernelTestCase
{

const SYNCHRONIZE_BOX_INFO_COMMAND_NAME = "app:synchronize-box-info";

public function setUp()
{
    parent::setUp();

    static::$kernel = static::createKernel();
    static::$kernel->boot();

    $application = new Application(static::$kernel);

    $this->command = $application->find(self::SYNCHRONIZE_BOX_INFO_COMMAND_NAME);
    $this->command->setApplication($application);
    $this->commandTester = new CommandTester($this->command);

    $this->entityManager = static::$kernel->getContainer()->get('doctrine.orm.entity_manager');
    $logger = $this->createMock(LoggerInterface::class);
    $this->rpcClientMock = $this->createMock(RpcClient::class);
    $application->add(new SynchronizeBoxInfoCommand($this->rpcClientMock, $logger, $this->entityManager));

}

public function testFirstExecutionAllNewData()
{
    $this->rpcClientMock->expects($this->once())
        ->method("callJsonRPCPostMethod")
        ->willReturn(["test"]);
    $this->commandTester->execute([
        'command' => $this->command,
    ]);
}

Для этого кода, когда я запускаю тест, команда, когда метод вызова команды callJsonRPCPostMethod, не возвращает смоделированную строку «test», но вызывает реальную реализацию метода, которая делает вызов api. Я искал весь интернет и на самом деле не нашел ни одного хорошего ответа, который бы работал для меня.

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Я обнаружил, что добавление команды с поддельными службами в приложение в конце setUp, после того, как $this->command = $application->find(...) заканчивается использованием команды перед проверенными службами. Поэтому перед тем, как использовать команду find, которую вы хотите протестировать, вы должны объявить команду с mocked сервисами. Этот код ниже работает для меня сейчас:

public function setUp()
{
    $kernel = self::bootKernel();

    $application = new Application($kernel);

    $this->entityManager = static::$kernel->getContainer()->get('doctrine.orm.entity_manager');
    $logger = $this->createMock(LoggerInterface::class);
    $this->rpcClientMock = $this->createMock(RpcClient::class);
    $application->add(new SynchronizeBoxInfoCommand($this->rpcClientMock, $logger, $this->entityManager));

    $this->command = $application->find(self::SYNCHRONIZE_BOX_INFO_COMMAND_NAME);
    $this->commandTester = new CommandTester($this->command);
}
0 голосов
/ 05 июля 2018

Сложно проверить такие вещи в Symfony4. Попробуйте сделать следующее:

1. Сделайте сервис, который вы хотите издеваться, публичным

2. В тесте макет:

$this->client = static::createClient();
static::$kernel->getContainer()->set($serviceId, $serviceMock);
$application = new Application(static::$kernel);

3. Используйте это $application для выполнения команды

$tester = (new CommandTester($application->find($commandName)))->setInputs($inputs);
$tester->execute($arguments);
...