Issues

ZF-5721: Annoying to debug test cases, Zend_Test_PHPUnit::dispatch() never throws FC exceptions

Description

Zend_Test_PHPUnit::dispatch() will always set the FC throw exceptions flag to false, this makes debugging test cases slightly more annoying and lengthy. Allowing the front controller to throw exceptions when using this method would help when tracking down any bugs in the text cases and/or the bootstraping required for testing controllers.

Here's a diff with a trivial fix

diff --git a/library/Zend/Test/PHPUnit/ControllerTestCase.php b/library/Zend/Test/PHPUnit/ControllerTestCase.php index 3885e00..67ecf76 100644 --- a/library/Zend/Test/PHPUnit/ControllerTestCase.php +++ b/library/Zend/Test/PHPUnit/ControllerTestCase.php @@ -146,7 +146,7 @@ abstract class Zend_Test_PHPUnit_ControllerTestCase extends PHPUnit_Framework_Te * @param string|null $url * @return void */ - public function dispatch($url = null) + public function dispatch($url = null, $throwExceptions = false) { // redirector should not exit $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector'); @@ -165,7 +165,7 @@ abstract class Zend_Test_PHPUnit_ControllerTestCase extends PHPUnit_Framework_Te $this->frontController ->setRequest($request) ->setResponse($this->getResponse()) - ->throwExceptions(false) + ->throwExceptions($throwExceptions) ->returnResponse(false); $this->frontController->dispatch(); }

Comments

oops, wikified version of the diff


diff --git a/library/Zend/Test/PHPUnit/ControllerTestCase.php b/library/Zend/Test/PHPUnit/ControllerTestCase.php
index 3885e00..67ecf76 100644
--- a/library/Zend/Test/PHPUnit/ControllerTestCase.php
+++ b/library/Zend/Test/PHPUnit/ControllerTestCase.php
@@ -146,7 +146,7 @@ abstract class Zend_Test_PHPUnit_ControllerTestCase extends PHPUnit_Framework_Te
      * @param  string|null $url
      * @return void
      */
-    public function dispatch($url = null)
+    public function dispatch($url = null, $throwExceptions = false)
     {
         // redirector should not exit
         $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
@@ -165,7 +165,7 @@ abstract class Zend_Test_PHPUnit_ControllerTestCase extends PHPUnit_Framework_Te
         $this->frontController
              ->setRequest($request)
              ->setResponse($this->getResponse())
-             ->throwExceptions(false)
+             ->throwExceptions($throwExceptions)
              ->returnResponse(false);
         $this->frontController->dispatch();
     }

I also had the same problem. IMHO the throwExceptions argument might be true by default. Test are executed in a command line environment, so there's no point is wrapping an exception in a error controller or similar one.

You know that you can always check the request object for the error_handler parameter, and pull the exception from that object, right? ;)

...OK (127 tests, 331 assertions) I have many integration tests and I just want to know quickly is something has exploded and front controller is serving a beatiful page (with menu and header and a nice formatted 40+ rows stacktrace in the middle) instead of the correct page. :)

I threw in my vote for this issue too. I had a view partial that was trying to load a partialLoop file that was unable to be found:

echo $this->partialLoop('viewPartialLoop.phtml', $this->publicCats);

The directory where viewPartialLoop.phtml is located was not in my include path. The exception I should have recieved was:

Fatal error: Uncaught exception 'Zend_View_Exception' with message 'script 'viewPartialLoop.phtml' not found in path ...

My testcase was only doing this:

    $this->dispatch('/Categories/view');
    $this->assertQueryContentContains( 'dd', 'bridals' );

The error I got was much more obscure, because ControllerTestCase sets frontController->throwExceptions(false):

    Zend_Dom_Exception: Error parsing document (type == docHtml)
    <path>ZendFramework-1.7.7\library\Zend\Dom\Query.php:190

This problem turned out to be very difficult to debug. I had to fire up a server, and point my config, etc, to the proper databases, and hit that controller/action to see the real problem. Alternatively, I could have just modified ControllerTestCase just long enough to see the real issue.

I think there are three possible solutions:

1) do as Matthew says and check the request object for the error_handler param and pull any exceptions (for EVERY controller dispatch test, ugh) 2) extend the ControllerTestCase class and override the dispatch function (again, ugh -- because ControllerTestCase->dispatch could change in the future) 3) ControllerTestCase should allow users to specify the 'throwExceptions" for the frontController object (PREFERRED -- and this is what I was trying to do in various ways until I finally looked at the ControllerTestCase->dispatch function)

That's my 2 cents. Thanks!

The ideal solution is to perhaps let me do this:


class MyControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{

    /**
     * I use this setUp method so make sure the front controller has the right default module configured,
     * as well as preventing the error handler from getting called.
     */
    // override
    public function setUp()
    {
        parent::setUp();
        $config = Zend_Registry::get('config');
        $this->frontController->setControllerDirectory(array(
                'default' => $config->document_root . '/../application/default/controllers'
                ));
        // TODO: ideally, I'd like to be able to do the next three lines, but until http://framework.zend.com/issues/browse/ZF-5721 is fixed,
        // these are meaningless because Zend_Test_PHPUnit_ControllerTestCase->dispatch sets these every time:
        $this->frontController->setParam('noErrorHandler', true);
        $this->frontController->throwExceptions(true);
        $this->frontController->returnResponse(true);
    }

}

@Matthew:

how about adding a second parameter:


public function dispatch($url, $throwExceptions=false)

For as long as I've been using ZF, I always have my testing environment report, log errors and throw exceptions.

The minimum I have set up in my "testing" section of my application.ini is the following:


[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1

One point of mentioning is that I use PHPUnit on CLI or within a CI system, but that shouldn't make a difference since tests are tests, no matter where they're run.

I agree that this should be fixed. Why not just let the user decide.

Index: library/Zend/Test/PHPUnit/ControllerTestCase.php
===================================================================
--- library/Zend/Test/PHPUnit/ControllerTestCase.php    (revision 23692)
+++ library/Zend/Test/PHPUnit/ControllerTestCase.php    (working copy)
@@ -196,7 +196,6 @@
         $this->frontController
              ->setRequest($request)
              ->setResponse($this->getResponse())
-             ->throwExceptions(false)
              ->returnResponse(false);
 
         if ($this->bootstrap instanceof Zend_Application) {

Please, this isn't a huge change. Even the patch is provided. When is it going to be commited?

Like Matthew Weier O'Phinney states use the error_handler param for debugging.

This works in my tests:

// get the errors $errors = $this->request->getParam('error_handler'); // throw the exception so it is apparent on cli when running tests throw new Zend_Exception($errors->exception);

Adding two-lines of code to unit tests is just an admission that this is indeed broken.

I want to use the config file as [~dragonbe] suggests, not add two-lines of code to every unit test or worse have to have maintain a base class that my unit tests inherit from.