lockManagerMock = $this->getMockBuilder(LockManagerInterface::class) ->getMockForAbstractClass(); $this->consumerFactory = $this->getMockBuilder(ConsumerFactory::class) ->disableOriginalConstructor() ->getMock(); $this->appState = $this->getMockBuilder(State::class) ->disableOriginalConstructor() ->getMock(); $this->writeFactoryMock = $this->getMockBuilder(WriteFactory::class) ->disableOriginalConstructor() ->getMock(); $this->objectManager = new ObjectManager($this); $this->command = $this->objectManager->getObject( StartConsumerCommand::class, [ 'consumerFactory' => $this->consumerFactory, 'appState' => $this->appState, 'writeFactory' => $this->writeFactoryMock, 'lockManager' => $this->lockManagerMock, ] ); parent::setUp(); } /** * Test for execute method. * * @param string|null $pidFilePath * @param bool $singleThread * @param int|null $multiProcess * @param int $lockExpects * @param bool $isLocked * @param int $unlockExpects * @param int $runProcessExpects * @param int $expectedReturn * @return void * @throws \Exception * @dataProvider executeDataProvider */ public function testExecute( ?string $pidFilePath, bool $singleThread, ?int $multiProcess, int $lockExpects, bool $isLocked, int $unlockExpects, int $runProcessExpects, int $expectedReturn ): void { $areaCode = 'area_code'; $numberOfMessages = 10; $batchSize = null; $consumerName = 'consumer_name'; $input = $this->getMockBuilder(InputInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $output = $this->getMockBuilder(OutputInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $input->expects($this->once())->method('getArgument') ->with(StartConsumerCommand::ARGUMENT_CONSUMER) ->willReturn($consumerName); $input->expects($this->exactly(6))->method('getOption') ->willReturnCallback(fn($param) => match ([$param]) { [StartConsumerCommand::OPTION_NUMBER_OF_MESSAGES] => $numberOfMessages, [StartConsumerCommand::OPTION_BATCH_SIZE] => $batchSize, [StartConsumerCommand::OPTION_AREACODE] => $areaCode, [StartConsumerCommand::PID_FILE_PATH] => $pidFilePath, [StartConsumerCommand::OPTION_SINGLE_THREAD] => $singleThread, [StartConsumerCommand::OPTION_MULTI_PROCESS] => $multiProcess }); $this->appState->expects($this->exactly($runProcessExpects))->method('setAreaCode')->with($areaCode); $consumer = $this->getMockBuilder(ConsumerInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $this->consumerFactory->expects($this->exactly($runProcessExpects)) ->method('get')->with($consumerName, $batchSize)->willReturn($consumer); $consumer->expects($this->exactly($runProcessExpects))->method('process')->with($numberOfMessages); if ($multiProcess !== null) { $consumerName .= '-' . $multiProcess; } $this->lockManagerMock->expects($this->exactly($lockExpects)) ->method('lock') ->with(md5($consumerName))//phpcs:ignore ->willReturn($isLocked); $this->lockManagerMock->expects($this->exactly($unlockExpects)) ->method('unlock') ->with(md5($consumerName)); //phpcs:ignore $this->assertEquals( $expectedReturn, $this->command->run($input, $output) ); } /** * @return array */ public static function executeDataProvider(): array { return [ [ 'pidFilePath' => null, 'singleThread' => false, 'multiProcess' => null, 'lockExpects' => 0, 'isLocked' => true, 'unlockExpects' => 0, 'runProcessExpects' => 1, 'expectedReturn' => Cli::RETURN_SUCCESS, ], [ 'pidFilePath' => '/var/consumer.pid', 'singleThread' => true, 'multiProcess' => null, 'lockExpects' => 1, 'isLocked' => true, 'unlockExpects' => 1, 'runProcessExpects' => 1, 'expectedReturn' => Cli::RETURN_SUCCESS, ], [ 'pidFilePath' => '/var/consumer.pid', 'singleThread' => true, 'multiProcess' => null, 'lockExpects' => 1, 'isLocked' => false, 'unlockExpects' => 0, 'runProcessExpects' => 0, 'expectedReturn' => Cli::RETURN_FAILURE, ], [ 'pidFilePath' => null, 'singleThread' => false, 'multiProcess' => 3, 'lockExpects' => 1, 'isLocked' => true, 'unlockExpects' => 1, 'runProcessExpects' => 1, 'expectedReturn' => Cli::RETURN_SUCCESS, ], [ 'pidFilePath' => null, 'singleThread' => false, 'multiProcess' => 3, 'lockExpects' => 1, 'isLocked' => false, 'unlockExpects' => 0, 'runProcessExpects' => 0, 'expectedReturn' => Cli::RETURN_FAILURE, ], ]; } /** * Test configure() method implicitly via construct invocation. * * @return void */ public function testConfigure() { $this->assertEquals(StartConsumerCommand::COMMAND_QUEUE_CONSUMERS_START, $this->command->getName()); $this->assertEquals('Start MessageQueue consumer', $this->command->getDescription()); /** Exception will be thrown if argument is not declared */ $this->command->getDefinition()->getArgument(StartConsumerCommand::ARGUMENT_CONSUMER); $this->command->getDefinition()->getOption(StartConsumerCommand::OPTION_NUMBER_OF_MESSAGES); $this->command->getDefinition()->getOption(StartConsumerCommand::OPTION_AREACODE); $this->command->getDefinition()->getOption(StartConsumerCommand::PID_FILE_PATH); $this->command->getDefinition()->getOption(StartConsumerCommand::OPTION_SINGLE_THREAD); $this->assertStringContainsString('To start consumer which will process', $this->command->getHelp()); } }