/usr/portage

Testing exception messages 5

Since PHPUnit 3.2.0 the former extension for exception test case (PHPUnit_Extension_ExceptionTest) has been merged back into the default test case. This allows you to use setExpextedException() in a normal test case. A simple exception test looks like that:

<?php
class MyTest extends PHPUnit_Framework_TestCase
{
    public function testException()
    {
        $this->setExpectedException('Exception');
        throw new Exception();
    }
    /**
     * @expectedException Exception
     */
    public function testException2()
    {
        throw new Exception()
    }
}

Often this is not enough. When you use a Zend Framework alike style for exceptions (one base class to rule them all) you often throw the same exception class with different messages. To test wheither the correct exception has been thrown, I discussed with Sebastian Bergmann about introducing an contains assertion for messages and this patch was applied. So in the current PHPUnit trunk you can test exception messages:

<?php
class MyTest extends PHPUnit_Framework_TestCase
{
    public function testException()
    {
        $this->setExpectedException('Exception', 'Exception message');
        throw new Exception('Exception message');
    }
    /**
     * @expectedException Exception Exception message
     */
    public function testException2()
    {
        throw new Exception('Exception message')
    }
}

As internally PHPUnit uses an assertContains for the exception message you can even test for incomplete strings like an exception message containing a random file name.

I proposed to do the same for exception codes but Sebastian did not agree. But let’s see, maybe that will change when Zend Framework is going to use exception codes a lot.

Filed under , , & five comments & one trackback

Trackbacks

Trackback specific URI for this entry

  1. Trackback from WEBLOG (/usr/portage)
    posted on January 18th 2008, 01:02:00 am Testing exceptions (2)

    As I previously mentioned we made some effort to better check exceptions. The target is not only ensuring that a various exception is thrown but also that this exception is really the one which is expected. The result was a patch for PHPUnit to test for

Comments

  1. dodger answers:
    published on December 26th 2007, 10:16:02 am *

    Hey Lars,
    nice idea – but let’s be honest – using Exception Messages is not really professional. Usually you should supply additional Information when throwing, to give more specific info – then your idea won’t work. I will discuss this with sebastian, I think he need to support the code – here you are 100% right. The Exception mechanism of ZF sucks, they will need to adopt it to something more useful.
    Anyway – really nice idea :)

    This is how I do test exceptions till now:

    try { .... } catch( Swoodoo_Exception $e) { if( $e->getCode() == Swoodoo_Exception::ACCOUNT_INVALID_ID) return; // OK }

    $this->fail();

    Reply

  2. Lars Strojny returns:
    published on December 26th 2007, 03:32:03 pm *

    I’m not sure about the "professional". At the end professional is what works on the long term. Checking the message works pretty fine to distinguish between different exceptions of the same exception class.

    Reply

  3. dodger states:
    published on December 27th 2007, 08:14:31 am *

    Lars,
    sorry if my comment was misleading – for sure I did not want to say that your idea is not professional – no way.
    Only that testing the message is not the right way ;) – let me make an example. Wrong Input, Message could be "Field ‘Name’ must not have any numbers". This Message could be generated automatically for all "char only" fields only the field name changes.
    If you work like this in a team then you can wait that somebody get the idea to test the message for the content e.g. "if strstr(mess,‘must not have a char’)" – and when you change the message e.g. for multilanguage reasons – then….

    Reply

  4. Lars Strojny opines:
    published on December 27th 2007, 08:25:37 am *

    Of course there are scenarios where this does not work as expected. No doubt.

    Reply

Add a Comment & let me know what you think