开发者

How to override var_export in PHPUnit?

开发者 https://www.devze.com 2023-01-25 00:43 出处:网络
In PHPUnit, there are times when an assertion fails, and when reporting the assertion, PHPUnit automa开发者_开发百科tically calls var_export() on the variable.Let\'s say you called this chunk of code:

In PHPUnit, there are times when an assertion fails, and when reporting the assertion, PHPUnit automa开发者_开发百科tically calls var_export() on the variable. Let's say you called this chunk of code:

$foo = new StdClass();
$foo->bar = 123;
$foo->baz = "Hi there";
$this->assertTrue($foo);

The output of that is:

Failed asserting that 
stdClass Object
(
   [bar] => 123
   [baz] => Hi there
)
is true.

If the variable is an Exception object, this can cause the unit test to print out megabytes of text when walking the object tree, including the stack traces and other info. Sometimes PHPUnit dies 'cause it runs out of memory trying to output it all.

I know one solution is to add an additional test, checking if the variable is an object before doing the assertTrue, or an assertEquals. But my team currently has a LOT of unit tests.

So I was wondering if there's a way to override PHPUnit's default behavior of calling var_export on a variable when generating the error report.

Thanks in advance.


After digging around some i didn't find a flag or something to achieve this so i tried to work backwards from the code:

The code in question (the print_r's) live in: PHPUnit_Framework_ComparisonFailure_Object's toString() method and i don't see a way of providing another implementation for that class without changeing code in phpunit (since the object gets created in a static call)

So for the sake of debugging you could change that in place but that ofc. leads to the usual problems you get when changing 3rd party code and since you said you've got a lot of code you might not want to do that since you rely on phpunit working as everyone expects.

A way that does not rely on changeing phpunit code and might be less hassle than going through all your tests and changeing all the assertTrue() calls might be something along those lines:

If all your tests use one base class it's even easier to put in:

<?php

class ErrorTest extends PHPUnit_Framework_TestCase {

    public function test1() {
        $foo = new StdClass();
        $foo->bar = 123;
        $foo->baz = "Hi there";
        $this->assertTrue($foo);
    }

    public static function assertTrue($x) {
        if(is_object($x)) {
            self::fail("Expecting True, got Object of Type: ".get_class($x));
        }
        parent::assertTrue($x);
    }
}

->

phpunit ErrorTest.php
PHPUnit 3.4.15 by Sebastian Bergmann.

F

Time: 0 seconds, Memory: 4.25Mb

There was 1 failure:

1) ErrorTest::test1
Expecting True, got Object of Type: stdClass

/home/mcsvnls/ErrorTest.php:15
/home/mcsvnls/ErrorTest.php:9

FAILURES!
Tests: 1, Assertions: 0, Failures: 1.

While i'm not sure thats a "good" solution it's the best i could come up with right now, maybe it helps :)

0

精彩评论

暂无评论...
验证码 换一张
取 消