More unit testing

On the way to work today I wrote some more unit tests for our internal framework. This time it was for a component that we use to fetch remote content. The component is called VG_Wget and one of its features is something called availability caching. What that does is that it caches the content of an URL in case it is unavailable the next time the content is fetched. There is a “regular” caching layer as well that can be enabled but the availability cache is only used when the external resource is unavailable.

I came up with a nice solution on how to test this, and since I’m such a nice guy I’ll share it with the lot of you.

Here is how we use the component:

<?php
require_once 'VG/Wget.php';
$wget = new VG_Wget();
$content = $wget->get('http://localhost/file.php'');

Since I know the contents of file.php I can easily check that the get method works as expected. But how can I make a file unavailable on the next request automagically? I’m glad you asked!

First I wrote a script that dynamically creates another php script, which in turn create some output, and then deletes itself.

The create.php script looks like this:

<?php
// Generate a filename and create the file
$filename = microtime(true) . '.php';
$fp = fopen($filename, 'w');

// String to write to the file
$contents = '<?php print(\'please cache me\'); unlink(__FILE__);';
fwrite($fp, $contents);

// Close the file
fclose($fp);

// Output the filename of the tmp file
print($filename);
&#91;/sourcecode&#93;

First we generate a unique filename, and then create a file with the following content:

&#91;sourcecode language="php"&#93;
<?php
print('please cache me');
unlink(__FILE__);
&#91;/sourcecode&#93;

After the file is created we output the unique filename so we know which file to fetch when testing the availability cache mechanism. When we access that file in a test the file will output "please cache me" and then self destruct. The next time we access that file the <em>VG_Wget</em> component will receive an HTTP 404, and the availability cache will be used instead.

The test method looks something like this:


<?php
class VG_Wget_WgetTest extends PHPUnit_Framework_TestCase {
    /**
     * Wget object
     *
     * @var VG_Wget
     */
    protected $wget = null;

    /**
     * Setup method
     */
    public function setUp() {
        $this->wget = new VG_Wget();
    }

    /**
     * Teardown method
     */
    public function tearDown() {
        $this->wget = null;
    }

    /**
     * Test method
     */
    public function testGetFileUsingAvailabilityCache() {
        // Base url
        $url = 'http://localhost/';

        // Call an url that creates a tmp file that is deleted after first request
        $tmpFilename = trim(file_get_contents($url . 'create.php'));

        $url .= $tmpFilename;

        // Fetch the file effectively deleting it so that the next request fails
        $content = trim($this->wget->get($url));

        // Fetch it again (this time the cache will be used)
        $content2 = trim($this->wget->get($url));

        $this->assertSame('please cache me', $content);
        $this->assertSame($content, $content2);
    }
}

I have removed some logic from the test method but you can see roughly how I test the component. Comments anyone?

Advertisements
This entry was posted in PHP, Technology, Work related and tagged , , . Bookmark the permalink.

One Response to More unit testing

  1. I have spending some time trying a UnitTest on Zend Framework. But, except for some configurations, is all the same.

    bye.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s