ZF2 PHPUnit - 测试控制器

ZF2 PHPUnit - Testing Controller

所以我决定深入研究 PHPUnit,并且我一直在阅读大量文档并在各处查找示例,但我遇到了一个我根本无法通过的错误。我希望有人能帮助指出我所缺少的东西。

可以找到我当前使用的文档here

这是我的项目树的样子:

LoginControllerTest.php

<?php

namespace LoginTest\Controller;

use LoginTest\Bootstrap;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;

/**
 * Class TestControllerTest
 *
 * @package LoginTest\Controller
 */
class TestControllerTest extends AbstractHttpControllerTestCase
{
    /**
     * Setup
     */
    public function setUp()
    {
        $this->setTraceError(true);

        $this->setApplicationConfig(
            Bootstrap::getConfig()
        );
    }

    /**
     * Index Action
     */
    public function testIndexActionCanBeAccessed()
    {
        $authenticationService = $this->getMockBuilder('Zend\Authentication\AuthenticationService')
                                      ->disableOriginalConstructor()
                                      ->getMock();

        $entityManager = $this->getMockBuilder('Doctrine\ORM\EntityManager')
                              ->disableOriginalConstructor()
                              ->getMock();

        $functionDates = $this->getMockBuilder('OTFunction\Service\Dates')
                              ->disableOriginalConstructor()
                              ->getMock();

        $functionEncryption = $this->getMockBuilder('OTFunction\Service\Encryption')
                                   ->disableOriginalConstructor()
                                   ->getMock();

        $functionIpaddress = $this->getMockBuilder('OTFunction\Service\Ipaddress')
                                  ->disableOriginalConstructor()
                                  ->getMock();

        $serviceManager = $this->getApplicationServiceLocator();

        $serviceManager->setAllowOverride(true);

        $serviceManager->setService(
            'Zend\Authentication\AuthenticationService',
            $authenticationService
        );

        $serviceManager->setService(
            'Doctrine\ORM\EntityManager',
            $entityManager
        );

        $serviceManager->setService(
            'OTFunction\Service\Dates',
            $functionDates
        );

        $serviceManager->setService(
            'OTFunction\Service\Encryption',
            $functionEncryption
        );

        $serviceManager->setService(
            'OTFunction\Service\Ipaddress',
            $functionIpaddress
        );

        $this->dispatch('/');

        $this->assertResponseStatusCode(200);
        $this->assertModuleName('Login');
        $this->assertControllerName('Login\Controller\Login');
        $this->assertControllerClass('LoginController');
        $this->assertMatchedRouteName('login');
    }

    /**
     * Index Action (Copy)
     */
    public function testIndexActionCanBeAccessedCopy()
    {
        $authenticationService = $this->getMockBuilder('Zend\Authentication\AuthenticationService')
                                      ->disableOriginalConstructor()
                                      ->getMock();

        $entityManager = $this->getMockBuilder('Doctrine\ORM\EntityManager')
                              ->disableOriginalConstructor()
                              ->getMock();

        $functionDates = $this->getMockBuilder('OTFunction\Service\Dates')
                              ->disableOriginalConstructor()
                              ->getMock();

        $functionEncryption = $this->getMockBuilder('OTFunction\Service\Encryption')
                                   ->disableOriginalConstructor()
                                   ->getMock();

        $functionIpaddress = $this->getMockBuilder('OTFunction\Service\Ipaddress')
                                  ->disableOriginalConstructor()
                                  ->getMock();

        $serviceManager = $this->getApplicationServiceLocator();

        $serviceManager->setAllowOverride(true);

        $serviceManager->setService(
            'Zend\Authentication\AuthenticationService',
            $authenticationService
        );

        $serviceManager->setService(
            'Doctrine\ORM\EntityManager',
            $entityManager
        );

        $serviceManager->setService(
            'OTFunction\Service\Dates',
            $functionDates
        );

        $serviceManager->setService(
            'OTFunction\Service\Encryption',
            $functionEncryption
        );

        $serviceManager->setService(
            'OTFunction\Service\Ipaddress',
            $functionIpaddress
        );

        $this->dispatch('/');

        $this->assertResponseStatusCode(200);
        $this->assertModuleName('Login');
        $this->assertControllerName('Login\Controller\Login');
        $this->assertControllerClass('LoginController');
        $this->assertMatchedRouteName('login');
    }
}

当我 运行 phpunit 我收到了预期的结果。

然而,当我复制完全相同的测试并更改函数名称并重新 运行 phpunit 时,我收到以下输出:

PHPUnit 4.4.5 by Sebastian Bergmann.

Configuration read from /vhosts/admin-application/vendor/otwebsoft/admin-login/test/phpunit.xml

.E

Time: 471 ms, Memory: 3.75Mb

There was 1 error:

1) LoginTest\Controller\TestControllerTest::testIndexActionCanBeAccessedCopy
Zend\ModuleManager\Listener\Exception\InvalidArgumentException: Config being merged must be an array, implement the Traversable interface, or be an instance of Zend\Config\Config. boolean given.

/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/ModuleManager/Listener/ConfigListener.php:342
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/ModuleManager/Listener/ConfigListener.php:127
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php:468
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php:207
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php:174
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php:96
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php:468
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php:207
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php:115
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php:252
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/Test/PHPUnit/Controller/AbstractControllerTestCase.php:164
/vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/Test/PHPUnit/Controller/AbstractControllerTestCase.php:178
/vhosts/admin-application/vendor/otwebsoft/admin-login/test/LoginTest/Controller/TestControllerTest.php:115
phar:///usr/bin/phpunit/phpunit/TextUI/Command.php:151
phar:///usr/bin/phpunit/phpunit/TextUI/Command.php:103

FAILURES!
Tests: 2, Assertions: 5, Errors: 1.

第 115 行是:

$serviceManager = $this->getApplicationServiceLocator();

我目前运行正在使用 Zend Framework 2.3.4 和 PHPUnit 4.4.5

如果我能提供任何其他信息,请告诉我。我在 Google 上翻了一页又一页,现在我完全不知所措了。

有什么想法吗?

编辑 1

我决定使用 Composer 重做我的整个项目来安装 ZF2 和我的模块。我按照 ZF2 单元测试指南来设置我的项目行。

编辑 2

我不确定为什么,但是如果我在 Bootstrap

中注释掉这一行
$serviceManager->get('ModuleManager')->loadModules();

然后测试运行没问题没问题。当我重新启用那一行代码时,它会抱怨合并配置。正如我们从 PHPUnit 错误中看到的那样,第一个测试 运行 很好,但第二个没有。

老实说,我不明白 loadModules() 函数有什么用,但如果禁用该单行就可以了,那很好。我只是觉得奇怪,它导致了这个问题。

我猜你误会了 PHP。

您的代码:

/**
 * Setup
 */
public function setUp()
{
    $this->setApplicationConfig(
        Bootstrap::config()
    );

    parent::setUp();
}

不在任何地方调用自动加载。 没有规定autoload函数会自动触发

选择 1,更改设置:

/**
 * Setup
 */
public function setUp()
{
    Bootstrap::autoload()

    $this->setApplicationConfig(
        Bootstrap::config()
    );

    parent::setUp();
}

还有另一种选择,就是这样。

我想通了...

我的 PHPUnit 设置是正确的,但是在 config/module.config.php 文件中我有:

public function getConfig()
{
    return include_once __DIR__ . '/config/module.config.php';
}

应该是:

public function getConfig()
{
    return include __DIR__ . '/config/module.config.php';
}

我想这可以解释为什么第一个测试会 运行 但其余测试不会。

这也解决了必须禁用 loadModules() 功能的问题。它现在已重新启用,一切似乎都在按预期工作。