symfony4命令测试中的模拟服务

时间:2018-07-04 14:19:08

标签: unit-testing service dependency-injection mocking symfony4

我对命令测试有疑问。我正在尝试在命令测试中模拟服务,但是存在一个问题,即该模拟未在测试中使用。

以下是命令代码:

    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 :(得分:0)

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

1.Make服务,您要模拟,公开

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

答案 1 :(得分:0)

我发现,在$this->command = $application->find(...)之后,将带有模拟服务的命令添加到应用程序中的setUp最终在模拟服务之前使用了命令。因此,在使用要测试的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);
}