Vinai Kopp

Magento Expert, Developer & Trainer

  • 05. The Route Config Kata

    March 21, 2016

    Mage2Katas

    This kata is about configuring a new route and creating an Action Controller.

    Why does it make sense to test-drive the creation of Action Controllers?
    We want our test to ensure our route configuration is correct and we also want the tests to catch conflicts with other extensions.

    As always for configuration, we will be using integration tests only during this kata.

    We don’t really care yet what our new action controller should do, as for now we are only focused on getting the routing right.

    The module name will be Mage2Kata_ActionController, so we can extend it in two weeks, when we get to the Action Controller Kata.
    I already created the module by following the steps of the skeleton module kata.

    Our tests will ensure our route is properly configured.

    The question we need to answer is how we can write tests against the route configuration present in a Magento 2 instance. We can use an instance of the \Magento\Framework\App\Route\ConfigInterface to do that.

    The first test goes in the file Mage2Kata/ActionController/Test/Integration/RouteConfigTest.php

    <?php
     
    namespace Mage2Kata\ActionController;
     
    use Magento\Framework\App\Route\ConfigInterface as RouteConfigInterface;
    use Magento\TestFramework\ObjectManager;
     
    class RouteConfigTest extends \PHPUnit_Framework_TestCase
    {
        /**
         * @magentoAppArea frontend
         */
        public function testRouteIsConfigured()
        {
            /** @var RouteConfigInterface $routeConfig */
            $routeConfig = ObjectManager::getInstance()->create(RouteConfigInterface::class);
            $this->assertContains('Mage2Kata_ActionController', $routeConfig->getModulesByFrontName('mage2kata'));
        }
    }

    Note that routes are always associated with either the frontend or the adminhtml area.
    We use the Magento integration test framework annotation @magentoAppArea frontend to specify the current area for the test.

    As long as our module is in the list of modules associated with the front name, the test will pass.

    Since there is no route configuration in place yet, the test does not pass.

    To change that, add the following configuration to the etc/frontend/routes.xml file:

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
        <router id="standard">
            <route id="mage2kata_actioncontroller" frontName="mage2kata">
                <module name="Mage2Kata_ActionController"/>
            </route>
        </router>
    </config>

    With the route configuration in place our first test passes.

    In case you have disabled TESTS_CLEANUP in your PHPUnit configuration dev/tests/integration/phpunit.xml, remember to clear the integration test sandbox directory before running the test.

    Time for the next test.

    Lets ensure that the configured route actually contains our new controller action.
    To do that, we can ask the base router to check if it can map a request to mage2kata/index/index to an action controller class.
    The base router is the Magento 2 equivalent of the standard router in Magento 1. It is responsible of processing requests with the (frontName}/{controller}/{action} request path structure.

    /**
     * @magentoAppArea frontend
     */
    public function testActionControllerIsFound()
    {
        $request = $this->objectManager->create(Request::class);
        $request->setModuleName('mage2kata');
        $request->setControllerName('index');
        $request->setActionName('index');
        /** @var BaseRouter $baseRouter */
        $baseRouter = $this->objectManager->create(BaseRouter::class);
        $expectedAction = \Mage2Kata\ActionController\Controller\Index\Index::class;
        $this->assertInstanceOf($expectedAction, $baseRouter->match($request));
    }

    Of course the test does not pass yet, since our module doesn’t contain any action controllers yet.

    All it takes to make the test pass is to create an empty shell of a controller action class.

    <?php
     
    namespace Mage2Kata\ActionController\Controller\Index;
     
    use Magento\Framework\App\Action\Action;
     
    class Index extends Action
    {
        public function execute()
        {
        }
    }

    Rerunning the tests brings us back to green.

    And with that the Route Config Mage2Kata is complete.

    I hope you enjoyed it!

    In the next episode we will continue to build out the Action class and test it’s behavior.

    As always, please let me know if you have any feedback, either as a comment below the video on youtube, or on twitter.

    Thanks for following!

    comments powered by Disqus