【问题标题】:ZF2 PHPUnit - Testing ControllerZF2 PHPUnit - 测试控制器
【发布时间】:2015-03-24 12:44:32
【问题描述】:

所以我决定深入研究 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() 函数与任何事情有什么关系,但如果我只需要禁用那一行就可以了。我只是觉得奇怪的是它导致了这个问题。

【问题讨论】:

  • 错误消息告诉您配置方法返回了不可遍历的内容(例如:数组)。您正在加载的任何模块是否具有返回非数组的Module::getConfig 方法?或者,如果您在引导期间从任何文件加载配置,这些配置不会返回数组吗?
  • 我所有的模块目前都返回一个配置数组,但我不确定引导程序。我什至没有想到这会造成问题,但我一定会检查一下。
  • 我已经清理了我的问题,希望它能更好地解释我的情况。 @AdamLundrigan 我还确保返回的所有内容都返回一个数组。
  • /vhosts/admin-application/vendor/otwebsoft/admin-login/test/LoginTest/Controller/TestControllerTest.php 第 160 行是什么?

标签: zend-framework2 phpunit


【解决方案1】:

我猜你在 PHP 中弄错了。

您的代码:

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

    parent::setUp();
}

不在任何地方调用自动加载。 没有自动触发自动加载功能的规则

选择1,改变setUp:

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

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

    parent::setUp();
}

还有另一种选择,走这条路。

【讨论】:

  • 实际上在 Bootstrap 内部调用了自动加载。反正我给了你一个选项,有很多随机错误。
【解决方案2】:

我想通了……

我的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() 功能解决了问题。它现在已重新启用,一切似乎都按预期工作。

【讨论】:

    猜你喜欢
    • 2016-01-31
    • 2015-04-22
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2010-12-28
    相关资源
    最近更新 更多