How to write and test your own head helper

Published on and tagged with cakephp  helper  testing

In CakePHP 1.1 the head helper by Miguel Ros was quite popular to add stuff to the head section of a HTML page from the view. CakePHP 1.2 provides such a functionality for referencing Javascript and CSS files. If you want to add something else to the head section, you have to write your own helper.

Let’s write a simple helper which creates an author meta tag.

Usually you write first the test, and then the application code. But in this case I will make an exception, as I think it is easier to understand if I write first the application code and then the test.

Writing the helper is straight-forward: we have to get the view and add the meta tag to this view:

// app/views/helpers/head.php
class HeadHelper extends AppHelper {
    function authorMetaTag($authorName) {
        $metaTag = '<meta name="author" content="'.$authorName.'">';
        $view = ClassRegistry::getObject('view');
        $view->addScript($metaTag);
    }
}

Before this helper can be used we have to add the following line to the head section of the (default) layout:

<?php echo $scripts_for_layout; ?>

With that we are ready to write our test (resp. we are finished with our work if we don’t write tests).

The test skeleton is easy:

class HeadHelperTest extends CakeTestCase {
    var $helper = null;

    function setUp() {
        $this->helper = new HeadHelper();
    }

    function testAuthorMetaTag() {
        $this->helper->authorMetaTag('cakebaker');
    }
}

As you have seen in the implementation of the helper, we retrieve a view object from the ClassRegistry. So to test our helper we also have to put a view object into the ClassRegistry. If you look at the source code of the view class constructor, you will see the view is automatically added to the ClassRegistry (to make sure the correct view is in the ClassRegistry we have to remove a possible view due to the behavior of ClassRegistry I explained in an earlier article). And you will also see that the constructor expects a controller object. As we don’t have any controller, we will use the AppController for this purpose.

loadController(null);

class HeadHelperTest extends CakeTestCase {
    var $helper = null;

    function setUp() {
        $this->helper = new HeadHelper();
    }

    function testAuthorMetaTag() {
        ClassRegistry::removeObject('view');
        $view = new View(new AppController());
        $this->helper->authorMetaTag('cakebaker');
    }
}

The last step is to render the view resp. the layout of the view and to check whether our meta tag has been added. For this purpose we can use the regular expression I described in “Regular expression to check for content between tags” and which was improved by BurntSushi.

loadController(null);

class HeadHelperTest extends CakeTestCase {
    var $helper = null;

    function setUp() {
        $this->helper = new HeadHelper();
    }

    function testAuthorMetaTag() {
        ClassRegistry::removeObject('view');
        $view = new View(new AppController());
        $this->helper->authorMetaTag('cakebaker');
        $renderedLayout = $view->renderLayout('');
        $this->assertPattern('#<head>.*?<meta name="author" content="cakebaker">.*?</head>#si', $renderedLayout);
    }
}

Now, we can run the test and should get a green bar.

Happy testing :)

5 comments baked

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License