您好我正在尝试为symfony4控制台命令创建单元测试,但我无法正确注入依赖项。我对symfony4很新,所以也许这对你们来说是个基本问题。
我的单元测试如下:
<?php
namespace App\Tests\Command;
use App\Command\ExecuteSalesTaskCommand;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Tester\CommandTester;
use Psr\Log\LoggerInterface;
use App\Repository\TaskRepository;
class ExeculteSalesTaskCommandTest extends KernelTestCase
{
/**
* @param LoggerInterface $logger
* @param TaskRepository $taskRepository
*/
public function testExecute(LoggerInterface $logger, TaskRepository $taskRepository)
{
$kernel = self::bootKernel();
$application = new Application($kernel);
$application->add(new ExecuteSalesTaskCommand($logger,$taskRepository));
# UPDATED
$logger = self::$kernel->getContainer()->get(LoggerInterface::class);
$taskRepository = self::$kernel->getContainer()->get(TaskRepository::class);
$command = $application->find('app:execute-sales-task');
$commandTester = new CommandTester($command);
$commandTester->execute(
[
'command' => $command->getName(),
]
);
// the output of the command in the console
$output = $commandTester->getDisplay();
$this->assertContains('Execute sales resulted: ', $output);
}
}
我的问题是我得到了这样的注射错误:
ArgumentCountError:函数参数太少 App \ Tests \ Command \ ExeculteSalesTaskCommandTest :: testExecute(),0 通过,正好2预期
更新: 当我从容器中取出依赖项时,我遇到了这种错误:
有1个错误:
1)App \ Tests \ Command \ ExeculteSalesTaskCommandTest :: testExecute Symfony的\分量\ DependencyInjection \异常\ ServiceNotFoundException的: “Psr \ Log \ LoggerInterface”服务或别名已被删除或 在编译容器时内联。你应该做到 public,或者直接停止使用容器并使用依赖项 注入而不是。
如何正确注入必要的依赖项,以便创建ExecuteSalesTaskCommand的实例?
答案 0 :(得分:1)
我也遇到类似的问题。但是跟随对我有用。我认为您不需要向应用程序添加命令并再次找到它?请找到以下解决方案。它可能会帮助别人。
<?php
// BaseCommandTester.php
/**
* This is basis for the writing tests, that will cover commands
*
*/
namespace App\Tests\Base;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Dotenv\Dotenv;
class BaseCommandTester extends KernelTestCase
{
/**
* @var
*/
private $application;
/**
* to set test environment and initiate application kernel
*/
public function setUp()
{
/**
* get test env
*/
$dotenv = new Dotenv();
$dotenv->load('/var/www/.env.test');
/**
* boot kernel
*/
$kernel = self::bootKernel();
$this->application = new Application($kernel);
parent::setUp();
}
/**
* @return mixed
*/
public function getApplication()
{
return $this->application;
}
/**
* @param mixed $application
*/
public function setApplication($application)
{
$this->application = $application;
}
}
测试用例
// FeedUpdaterCommandTest.php
<?php
namespace App\Tests\Command;
use App\Tests\Base\BaseCommandTester;
use Symfony\Component\Console\Tester\CommandTester;
class FeedUpdaterCommandTest extends BaseCommandTester
{
/**
* test to update all feeds
*/
public function testExecuteUpdateAll() {
/**
* init command tester and executre
*/
$commandName = 'app:feedUpdater';
$expectedResult = '[OK] Update Success Feed Type : All';
$command = $this->getApplication()->find($commandName);
$commandTester = new CommandTester($command);
$commandTester->execute(array(
'command' => $command->getName()
));
/**
* get result and compare output
*/
$result = trim($commandTester->getDisplay());
$this->assertEquals($result, $expectedResult);
}
}
试运行结果
#Run tests
root@xxx:/var/www# bin/phpunit tests/Command
#!/usr/bin/env php
PHPUnit 6.5.13 by Sebastian Bergmann and contributors.
Testing tests/Command
2018-11-28T07:47:39+00:00 [alert] Successful update of popularProducts Feeds!
2018-11-28T07:47:39+00:00 [alert] Successful update of topVouchers Feeds!
. 1 / 1 (100%)
Time: 1.44 seconds, Memory: 12.00MB
OK (1 test, 1 assertion)
我正在使用以下Sf4版本
-------------------- --------------------------------------
Symfony
-------------------- --------------------------------------
Version 4.1.7
服务定义及其默认为私有
#config/services.yml
App\Service\FeedGenerator:
arguments:
$feeds: '%feed_generator%'
我认为您无需再次自动接线。
答案 1 :(得分:0)
我发现问题是我尝试手动加载依赖项。使用自动装配,如下所示:
public function testExecute()
{
$dotenv = new Dotenv();
$dotenv->load(__DIR__.'/.env.test');
$kernel = self::bootKernel();
$application = new Application($kernel);
$executeSalesCommand = self::$kernel->getContainer()->get(
'console.command.public_alias.App\Command\ExecuteSalesTaskCommand'
);
$application->add($executeSalesCommand);
$command = $application->find('app:execute-sales-task');
$commandTester = new CommandTester($command);
$commandTester->execute(
[
'command' => $command->getName(),
]
);
// the output of the command in the console
$output = $commandTester->getDisplay();
// do your asserting stuff
}
您需要从内核容器中获取命令。现在它有效。