《Zend Framework2.0最新版本快速入门手册》【第三篇】单元测试(CSDN首发中!!支持围观)

在大型项目开发中,坚实可靠的单元测试是非常重要的事情,尤其对那些经过很多的人经手的项目。回到过去人工手动的针对每一次改变,然后测试一个应用里面的,每一个单独的组件,这个是不可能的事情了。所以你的单元测试将会帮助你减轻测试应用组件的工作量,和改变你写测试的时候出现有些东西莫名其妙不能工作的状况。

Zend框架2 的API使用PHPUnit作为测试工具,所以本教程中的应用用的也是这个工具。有关PHPUnit的详细教程内容超出了本教程的范围,所以这里我们针对下面相关页面展示的内容,提供一个测试范例。这个教程是假定你已经安装了PHPUnit。

安装测试文件夹

zf2-tutorial\module\Application中创建一个子文件夹叫做test ,整个文件夹结构如下:

zf2-tutorial/
    /module
        /Application
            /test
                /ApplicationTest
                    /Controller

test 文件夹的结构,是跟组件的源文件结构相对应的,这样做的好处是可以让你在测试的时候,依照良好的文件组织结构,容易查找对应的文件.

开始启动你的测试

zf2-tutorial/module/Application/test路径下,接下来创建一个phpunit.xml.dist文件:

<?xml version="1.0" encoding="UTF-8"?>

<phpunit bootstrap="Bootstrap.php">
    <testsuites>
        <testsuite name="zf2tutorial">
            <directory>./ApplicationTest</directory>
        </testsuite>
    </testsuites>
</phpunit>

A file called Bootstrap.php, also underzf-tutorial/module/Application/test:.组件中有个文件是Bootstrap.php,那么同样在zf-tutorial/module/Application/test下面也有一个类似的文件:这个文件是由Evan写的,可以直接用,不过就是把命名空间改一下就可以了

<?php
namespace ApplicationTest;//记得在你的测试代码里面记得修改这个命名空间

use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use RuntimeException;

error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);

class Bootstrap
{
    protected static $serviceManager;
    protected static $config;
    protected static $bootstrap;

    public static function init()
    {
        // Load the user-defined test configuration file, if it exists; otherwise, load
        if (is_readable(__DIR__ . '/TestConfig.php')) {
            $testConfig = include __DIR__ . '/TestConfig.php';
        } else {
            $testConfig = include __DIR__ . '/TestConfig.php.dist';
        }

        $zf2ModulePaths = array();

        if (isset($testConfig['module_listener_options']['module_paths'])) {
            $modulePaths = $testConfig['module_listener_options']['module_paths'];
            foreach ($modulePaths as $modulePath) {
                if (($path = static::findParentPath($modulePath)) ) {
                    $zf2ModulePaths[] = $path;
                }
            }
        }

        $zf2ModulePaths  = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR;
        $zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS') ? ZF2_MODULES_TEST_PATHS : '');

        static::initAutoloader();

        // use ModuleManager to load this module and it's dependencies
        $baseConfig = array(
            'module_listener_options' => array(
                'module_paths' => explode(PATH_SEPARATOR, $zf2ModulePaths),
            ),
        );

        $config = ArrayUtils::merge($baseConfig, $testConfig);

        $serviceManager = new ServiceManager(new ServiceManagerConfig());
        $serviceManager->setService('ApplicationConfig', $config);
        $serviceManager->get('ModuleManager')->loadModules();

        static::$serviceManager = $serviceManager;
        static::$config = $config;
    }

    public static function getServiceManager()
    {
        return static::$serviceManager;
    }

    public static function getConfig()
    {
        return static::$config;
    }

    protected static function initAutoloader()
    {
        $vendorPath = static::findParentPath('vendor');

        if (is_readable($vendorPath . '/autoload.php')) {
            $loader = include $vendorPath . '/autoload.php';
        } else {
            $zf2Path = getenv('ZF2_PATH') ?: (defined('ZF2_PATH') ? ZF2_PATH : (is_dir($vendorPath . '/ZF2/library') ? $vendorPath . '/ZF2/library' : false));

            if (!$zf2Path) {
                throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
            }

            include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';

        }

        AutoloaderFactory::factory(array(
            'Zend\Loader\StandardAutoloader' => array(
                'autoregister_zf' => true,
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/' . __NAMESPACE__,
                ),
            ),
        ));
    }

    protected static function findParentPath($path)
    {
        $dir = __DIR__;
        $previousDir = '.';
        while (!is_dir($dir . '/' . $path)) {
            $dir = dirname($dir);
            if ($previousDir === $dir) return false;
            $previousDir = $dir;
        }
        return $dir . '/' . $path;
    }
}

Bootstrap::init();

还有个文件叫做 TestConfig.php.dist

<?php
return array(
    'modules' => array(
        'Application',
    ),
    'module_listener_options' => array(
        'config_glob_paths'    => array(
            '../../../config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths' => array(
            'module',
            'vendor',
        ),
    ),
);

这基本上跟config/application.config.php一样,但是我们只定义跟测试有关的组件

你的第一个测试控制器

接下来,zf-tutorial/module/Application/test/ApplicationTest/Controller下创建一个IndexControllerTest.php,内容如下:

<?php

namespace ApplicationTest\Controller;

use ApplicationTest\Bootstrap;
use Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter;
use Application\Controller\IndexController;
use Zend\Http\Request;
use Zend\Http\Response;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;
use PHPUnit_Framework_TestCase;

class IndexControllerTest extends PHPUnit_Framework_TestCase
{
    protected $controller;
    protected $request;
    protected $response;
    protected $routeMatch;
    protected $event;

    protected function setUp()
    {
        $serviceManager = Bootstrap::getServiceManager();
        $this->controller = new IndexController();
        $this->request    = new Request();
        $this->routeMatch = new RouteMatch(array('controller' => 'index'));
        $this->event      = new MvcEvent();
        $config = $serviceManager->get('Config');
        $routerConfig = isset($config['router']) ? $config['router'] : array();
        $router = HttpRouter::factory($routerConfig);

        $this->event->setRouter($router);
        $this->event->setRouteMatch($this->routeMatch);
        $this->controller->setEvent($this->event);
        $this->controller->setServiceLocator($serviceManager);
    }
}

这里,依照Tom Oram的一篇日志Unit Testing a ZF 2 Controller里面的内容,做一点扩展,就是在setUp()方法然后直接在控制其中设置EventManager和ServiceLocator。虽然这个不是很重要目前,但是我们需要在后面进一步写更多测试内容的时候,需要用到它。

现在,添加下面的方法函数到IndexControllerTest 类中去:

public function testIndexActionCanBeAccessed()
{
    $this->routeMatch->setParam('action', 'index');

    $result   = $this->controller->dispatch($this->request);
    $response = $this->controller->getResponse();

    $this->assertEquals(200, $response->getStatusCode());
}

这个测试是检查首页回应的http状态码是否为200,并且控制器的返回值是否是一个Zend\View\Model\ViewModel对象。

开始测试!!

最后, cd zf-tutorial/module/Application/test/ 然后开始unit下. 如果你看到如下提示,你的测试结果成功!

PHPUnit 3.5.15 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 5.75Mb

OK (1 test, 2 assertions)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值