2

I have a Zend Framework application with modules and I want to setup PHPUnit testing.

This is the project folder

- project/
   -application/
      - controllers/
          - indexController.php
      - modules/
         - mycore/
            - controllers/
                -  ActionsController.php
            - views/
                - ...
   - ...
   - tests/
      - application/
         - controllers/
            -IndexControllerTest.php
         - modules/
            - mycore/
                - controllers/
                   - ActionsControllerTest.php
      ControllerTestCase.php
      Bootstrap.php
      phpunit.xml

This is the content of each setup file in the test folder

ControllerTestCase.php

require_once 'Zend/Application.php';
require_once 'Zend/Auth.php';
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';

class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {
    protected $application

    public function setUp() {
        $this->bootstrap = array($this, 'appBootstrap');
        parent::setUp();
    }

    public function appBootstrap() {
        $this->application = new Zend_Application(
            APPLICATION_ENV,
            APPLICATION_PATH . '/configs/application.ini');
        $bootstrap = $this->application->getBootstrap()->bootstrap();

        $front = Zend_Controller_Front::getInstance();
        $front->setControllerDirectory(APPLICATION_PATH . '/controllers','default');
        $front->addModuleDirectory(APPLICATION_PATH . '/modules');

        return $bootstrap;
    }

    public function tearDown() {
        Zend_Auth::getInstance()->clearIdentity();
        $this->resetRequest();
        $this->resetResponse();
        parent::tearDown();
    }

    protected  function _doLogin($identity = null) {
        if ( $identity === null ) {
            $identity = $this->_generateFakeIdentity();
        }
        Zend_Auth::getInstance()->getStorage()->write( $identity );
    }

    protected function _generateFakeIdentity() {
        $identity = new stdClass();
        $identity->RecID                     = 3;
        $identity->user_firstname            = '****';
        $identity->user_lastname             = '********';
        $identity->confirmed                 = true;
        $identity->enabled                   = true;

        return $identity;
    }

    protected  function _doLogout() {
        Zend_Auth::getInstance()->clearIdentity();
    }
}

Bootstrap.php

error_reporting(E_ALL);
// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

require_once 'Zend/Loader/Autoloader.php';

phpunit.xml

<phpunit bootstrap="./bootstrap.php" colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true" >
    <testsuite name="Application Test Suite">
        <directory>./</directory>
    </testsuite>
    <testsuite name="Library Test Suite">
        <directory>./library</directory>
    </testsuite>

    <filter>
        <!-- If Zend Framework is inside your project's library, uncomment this filter -->
        <!-- 
        <whitelist>
            <directory suffix=".php">../../library/Zend</directory>
        </whitelist>
        -->
    </filter>
</phpunit>

And this is the content of the module test

ActionsControllerTest.php

class Mycore_ActionsControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{

    public $module;

    public function setUp()
    {
        $this->module = 'mycore';
        $this->bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
        $_SERVER['HTTP_HOST'] = 'unittest_host';
        $_SERVER['REQUEST_URI'] = '/';
        parent::setUp();
    }

    public function testIndexAction()
    {
        $this->dispatch("/");
        // assertions
        $this->assertModule('mycore');
        $this->assertController('actions');
        $this->assertAction('index');        
    }


}

And this is the result:

Starting test 'IndexControllerTest::testIndexAction'.
.
Starting test 'Mycore_ActionsControllerTest::testIndexAction'.
F

Time: 1 second, Memory: 14.00Mb

There was 1 failure:

1) Mycore_ActionsControllerTest::testIndexAction
Failed asserting last module used <"default"> was "mycore"

/project/library/Zend/Test/PHPUnit/ControllerTestCase.php:929
/project/tests/application/modules/mycore/controllers/ActionsControllerTest.php:21

All the tests within a module are working fine but when I start testing module controllers I get this error. I have searched all over the internet but couldn't find a fix for this error, so I hope someone can help me.

2 Answers 2

3

What you are getting is not an error, it is a failing test.

That's probably happening because you are dispatching to '/' which looks for the default action in the default controller of the default module. If you dispatch to '/mycore' or '/mycore/actions/index' you will probably find the test passes.

For your test to pass without changing it you will need to change your default route to point to '/mycore/actions/index'.

Sign up to request clarification or add additional context in comments.

6 Comments

that explains why this wasn't working correct. But i did some changes to my test case so i does a dispatch to /mycore/actions/index (normal the application should redirect to /user/login). But now the tests doesn't give a Fail if i check for the module 'mycore' controller 'actions' and action 'index'. I don't even get any response (no . or F or E ). How can i debug this to get a clear error message? Thanks in advance!
That means the test is passing. You don't seem to have any logging set up in your phpunit.xml. Have a look at this as an example of how to set it up.
Don't you get a '.' when a test passes? The index controller gets a . and this one doesn't get any resonse. Ok i just saw your edit, i will check that. Thanks!
I added the loggin part and for the general index controller it looks like it passes (i get IndexController --> IndexControllerTest but for the Mycore_ActionsController i don't get any thing. So no passed test? but no debugging info. I also used a visual interface for phpunit and this gave me this error "Failed asserting last module used <"default"> was "user" so still a problem with the module. Is there maybe also a way to get the current page you are at from phpunit? so i can check if the redirect goes well. Thanks!
You can echo out anything you want in the test as you would in any php file. Something like echo "I'm here"; will appear in the PHPUnit output.
|
0

I had the same issue. For me it happens because the request was redirected to the 'ErrorController'. You can check this by commenting your assertModule line. If you got an error like this one 'Failed asserting last controller used <"error"> was "actions"' we're in the same case. There can be various reasons for this kind of error. You've got to catch the error. After the dispatch you can retreive the exceptions like this :

$response = $this->getResponse();
$exceptions = $response->getException();
// do whatever you want, mail, log, print

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.