How to setup unit test for magento command

The following article shows you how to unit test a magento command object. It has minor difference to how we test other classes in magento. The good news is that everything works fine and your code is highly reliable like the rest of the application.

Example command object code

namespace Company\Module\Console\Command;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magento\Framework\App\State;
use Magento\Framework\App\Area;
use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Command\Command;

class ProcessOrdersCommand extends Command
{

    /** @var State */
    private $appState;

    /**
     * ProcessOrdersCommand constructor.
     * @param State $state
     * @param string|null $name
     */
    public function __construct(
        State $state,
        ?string $name = null
    ) {
        parent::__construct($name);
        $this->appState = $state;
    }

    protected function configure(): void
    {
        $this->setName('your-company:subject:task')
            ->setDescription('Your command description');

        parent::configure();
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @throws LocalizedException
     */
    protected function execute(InputInterface $input, OutputInterface $output): void
    {
        $output->writeln('command started');
        $this->appState->setAreaCode(Area::AREA_GLOBAL);
        $output->writeln('command ended');
    }
}

How to setup your unit test for the magento command

namespace Company\Module\Test\Unit\Console\Command;

use Magento\Framework\App\State;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

class ProcessOrdersCommandTest extends TestCase
{
    public function testExecuteWithSuccess(): void
    {
        $applicationCommand = $this->getApplication();
        $commandTester = new CommandTester($applicationCommand);
        $commandTester->execute([]);
    }

    public function testSomeMessageFromConsoleLog(): void
    {
        $applicationCommand = $this->getApplication();
        $commandTester = new CommandTester($applicationCommand);
        $commandTester->execute([]);
        $commandOutput = $commandTester->getDisplay();
        $this->assertContains('command started', $commandOutput);
    }

    /**
     * @return PHPUnit_Framework_MockObject_MockObject|State
     */
    private function getStateMock(): PHPUnit_Framework_MockObject_MockObject
    {
        return $this->createMock(State::class);
    }

    /**
     * @return ProcessOrdersCommand
     */
    private function getApplication(): ProcessOrdersCommand
    {
        $application = new Application();
        $commandObject = $this->getCommandWithMocks();
        $application->add($commandObject);

        /** @var ProcessOrdersCommand $object */
        $object = $application->find('your-company:subject:task');
        return $object;
    }

    /**
     * @return ProcessOrdersCommand
     */
    private function getCommandWithMocks(): ProcessOrdersCommand
    {
        return new ProcessOrdersCommand(
            $this->getStateMock()
        );
    }
}
what clients say about us

Client testimonials

Our sites look great and run smoothly. Thanks for all your hard work and patience in getting us to where we are today.

contact us

Contact Us

If you have questions or want us to send you a quote for project please email us.

latest news

Articles

PHPUnit mock magic functions
Learn more about PHPUnit Partial Mock.