<?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 MVC test cases should extend
        <classname>Zend_Test_PHPUnit_ControllerTestCase</classname>. This class in turn
        extends <code>PHPUnit_Framework_TestCase</code>, 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 MVC
        implementation.
    </para>

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

    <para>
        First, 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>
        Second, you can provide a PHP 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 <code>setUp()</code> 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 <code>parent::setUp()</code>; this is necessary, as
        the <code>setUp()</code> method of
        <classname>Zend_Test_PHPUnit_Controller_TestCase</classname> will perform the
        remainder of the bootstrapping process (which includes calling the
        callback).
    </para>

    <para>
        During normal operation, the <code>setUp()</code> 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
        <code>include</code> the file specified in <code>$bootstrap</code>, 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_Controller_TestCase</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:
-->
