symfony4命令测试中的模拟服务

Mock service in symfony4 command 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 它不会 return 模拟字符串 "test" 但它调用真实方法的实现,调用 api。我正在搜索整个互联网,但实际上没有找到任何适合我的好答案。

在 Symfony4 中很难测试这些东西。 尝试执行以下操作:

1.Make 您要模拟的服务,public

2.In 测试模拟:

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

3.Use 这个$application 用于命令执行

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

我发现在设置结束时向应用程序添加带有模拟服务的命令,在 $this->command = $application->find(...) 结束后在模拟服务之前使用命令。因此,在使用要测试的 find 命令之前,您应该使用模拟服务声明命令。下面这段代码现在对我有用:

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);
}