PhpUnit - mock extended php exception object

I am testing some old code that extends the default php exception object. This code displays its own HTML error message.

I would like to mock this exception object in such a way that when the code under test throws an exception, it will just echo the main message instead of giving me the entire HTML message.

I cannot figure out how to do this. It looks like you can check for explicit exceptions, but you cannot change the general way the exception behaves, and you also cannot mock an object that extends php's default functionality. (can't think of any other example of this exception except ... but it looks like it does)

I guess the problem is where would you attach the mocking object? It looks like you can't interfere with "throw new" and this is where the object's method is called ....

Or, if you can somehow use phpunit's existing exception functionality to change the behavior of the exception the way you want, in general for all your code ... but it looks like that would be a hack and bad ...

EDIT: Here's some code to make things clearer:

class FooTest extends PHPUnit_Framework_TestCase{

    public function testBar(){
        include '/path/to/file.php'; //generates exception

        $this->assertTrue($baz);             
    }
}
 ...
//overridden exception class
class Foo_Exception extends ErrorException{
 ...

      

So my question is, is there a way to deal with this overridden class without doing it on a case-by-case basis? what if I am not testing the behavior of the exception, just the code that raises the exception?

+2


a source to share


3 answers


First, I'll write a test that captures the exception-throwing behavior:

include '/path/to/file.php'; //generates exception
public function testCatchFooException() {
    try {
        $this->assertTrue($baz);             
    }
    catch (Exception $expected) {
        $this->assertEquals('This is expected html from exception', $expected->getMessage());
        return;
    }

    $this->fail('An expected Exception has not been raised Foo_Excpetion.');
}

      

You can now do a few things with this coating test. You can either fix the exception or fix the code that throws the exception.

Another thing you can do is wrap the entire file.php class in a class:

 class FooClass {

    function runFoo() {
        include '/path/to/file.php'; //generates exception

    }   

}

      

Then add tests while using the extract method until you throw the exception.

[EDIT]

Here's some serious procedural code:



<?php
require_once 'helper.php';  //helper file

function countNewMessages($user_id) {
}

function countNewOrders() {
}

function countNewReturns() {
}

function getDB($init = NULL) {
}

function getDisplay() {
}

getDisplay();

?>

      

And here is the wrapped class:

<?php
require_once '';  //helper file

class Displayer {
    function countNewMessages($user_id) {
    }

    function countNewOrders() {
    }

    function countNewReturns() {
    }

    function getDB($init = NULL) {
    }

    function getDisplay() {
    }
}
?>

      

And now I can check it:

    function testGetDisplay() {
    $display = new Displayer();

    $this->assertEquals('html code', $display->getDisplay());
}

      

And test individual functions in it. And if I continue to germinate methods on it.

The above test will be considered a coverage test. There may be mistakes, but that's what it does. As I sprout the methods, I get more code coverage from the tests, sprouting so that I can make sure I don't break the exit.

+1


a source


PHP extreme exception object "prints" error page on "costum" page? Do you mean that his error message is a complete HTML page? It's not very smart ...

What you can do is replace the default exception handler (see this function ), call getMessage on the exception, and parse the HTML error page to retrieve the message. Then you can print the error message and kill the script. Like this (in PHP 5.3):



set_exception_handler(
    function (Exception $e) {
        die(parse_html_error_page($e->getMessage()));
    }
);

      

0


a source


Ok, I misunderstood the question. If the script under test catches the error and then repeats the error page, then this has nothing to do with exceptions. You can use the ob_ family:

ob_start();
include $file;
$contents = ob_get_contents();

if (result_is_error($contents))
    die(extract_error_from_result($contents));
else
    echo $contents;

ob_end_clean();

      

0


a source







All Articles