<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect2 id="zend.test.phpunit.bootstrapping">
    <title>Bootstrapping your TestCase</title>

    <para>
        As noted in the <link linkend="zend.test.phpunit.loginexample">Login
            example</link>, all <acronym>MVC</acronym> test cases should extend
        <classname>Zend_Test_PHPUnit_ControllerTestCase</classname>. This class in turn
        extends <classname>PHPUnit_Framework_TestCase</classname>, and gives you all the
        structure and assertions you'd expect from PHPUnit -- as well as some
        scaffolding and assertions specific to Zend Framework's <acronym>MVC</acronym>
        implementation.
    </para>

    <para>
        In order to test your <acronym>MVC</acronym> application, you will need to bootstrap it.
        There are several ways to do this, all of which hinge on the public
        <varname>$bootstrap</varname> property.
    </para>

    <para>
        First, and probably most straight-forward, simply create a
        <classname>Zend_Application</classname> instance as you would in your
        <filename>index.php</filename>, and assign it to the <varname>$bootstrap</varname> property.
        Typically, you will do this in your <methodname>setUp()</methodname> method; you will need
        to call <methodname>parent::setUp()</methodname> when done:
    </para>

    <programlisting language="php"><![CDATA[
class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    public function setUp()
    {
        // Assign and instantiate in one step:
        $this->bootstrap = new Zend_Application(
            'testing',
            APPLICATION_PATH . '/configs/application.ini'
        );
        parent::setUp();
    }
}
]]></programlisting>

    <para>
        Second, you can set this property to point to a file. If you do
        this, the file should <emphasis>not</emphasis> dispatch the front
        controller, but merely setup the front controller and any application
        specific needs.
    </para>

    <programlisting language="php"><![CDATA[
class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    public $bootstrap = '/path/to/bootstrap/file.php'

    // ...
}
]]></programlisting>

    <para>
        Third, you can provide a <acronym>PHP</acronym> callback to execute in order to bootstrap
        your application. This method is seen in the <link
            linkend="zend.test.phpunit.loginexample">Login example</link>. If
        the callback is a function or static method, this could be set at the
        class level:
    </para>

    <programlisting language="php"><![CDATA[
class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    public $bootstrap = array('App', 'bootstrap');

    // ...
}
]]></programlisting>

    <para>
        In cases where an object instance is necessary, we recommend performing
        this in your <methodname>setUp()</methodname> method:
    </para>

    <programlisting language="php"><![CDATA[
class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    public function setUp()
    {
        // Use the 'start' method of a Bootstrap object instance:
        $bootstrap = new Bootstrap('test');
        $this->bootstrap = array($bootstrap, 'start');
        parent::setUp();
    }
}
]]></programlisting>

    <para>
        Note the call to <methodname>parent::setUp()</methodname>; this is necessary, as
        the <methodname>setUp()</methodname> method of
        <classname>Zend_Test_PHPUnit_ControllerTestCase</classname> will perform the
        remainder of the bootstrapping process (which includes calling the
        callback).
    </para>

    <para>
        During normal operation, the <methodname>setUp()</methodname> method will bootstrap
        the application. This process first will include cleaning up the
        environment to a clean request state, resetting any plugins and
        helpers, resetting the front controller instance, and creating new
        request and response objects. Once this is done, it will then either
        <methodname>include()</methodname> the file specified in <varname>$bootstrap</varname>, or
        call the callback specified.
    </para>

    <para>
        Bootstrapping should be as close as possible to how the application
        will be bootstrapped. However, there are several caveats:
    </para>

    <itemizedlist>
        <listitem>
            <para>
                Do not provide alternate implementations of the Request and
                Response objects; they will not be used.
                <classname>Zend_Test_PHPUnit_ControllerTestCase</classname> uses custom
                request and response objects,
                <classname>Zend_Controller_Request_HttpTestCase</classname> and
                <classname>Zend_Controller_Response_HttpTestCase</classname>, respectively.
                These objects provide methods for setting up the request
                environment in targeted ways, and pulling response artifacts in
                specific ways.
            </para>
        </listitem>

        <listitem>
            <para>
                Do not expect to test server specifics. In other words, the tests
                are not a guarantee that the code will run on a specific server
                configuration, but merely that the application should run as
                expected should the router be able to route the given request. To
                this end, do not set server-specific headers in the request object.
            </para>
        </listitem>
    </itemizedlist>

    <para>
        Once the application is bootstrapped, you can then start creating
        your tests.
    </para>
</sect2>
<!--
vim:se ts=4 sw=4 et:
-->
