php - ZF2 - Module.php 中请求的模拟服务

标签 php testing zend-framework2 phpunit

我正在尝试测试我的 ZF2 应用程序的 Controller 。假设这个 Controller 在我的 A 模块中。

在模块 AModule.phponBootstrap 方法中,我正在使用服务管理器检索另一个模块的服务,说 B,我没有加载。

如何在服务管理器中设置请求服务的模拟?请注意,我不能在我的测试中使用 $this->getApplicationServiceLocator() 来执行此操作,因为这已经调用了我的 A 的 Module.onBootstrap 方法 模块。

为了发布一些代码,这就是我目前正在做的事情

bootstrap.php

namespace Application;

use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use RuntimeException;

class Bootstrap
{
    protected static $serviceManager;

    public static function init()
    {
        $modulePath = static::findParentPath('module');
        $vendorPath = static::findParentPath('vendor');

        if (is_readable($vendorPath . '/autoload.php')) {
            $loader = include $vendorPath . '/autoload.php';
        } else {
            throw new RuntimeException('Cannot locate autoload.php');
        }

        $config = [
            'modules' => [
                'Application',
            ],
            'module_listener_options' => [
                'module_paths' => [
                    $modulePath,
                    $vendorPath
                ]
            ]
        ];

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

    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;
    }

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

Bootstrap::init();

我的实际测试课

namespace Application\Functional;

use Application\Bootstrap;

use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;

class ValidateCustomerRegistrationTest extends AbstractHttpControllerTestCase
{
    public function setUp()
    {
        $serviceManager = Bootstrap::getServiceManager();
        $applicationConfig = $serviceManager->get('ApplicationConfig');

        $this->setApplicationConfig($applicationConfig);
        parent::setUp();
    }

    public function testRegisterValidUserWithOnlyEquomobiliData()
    {
        $this->getApplicationServiceLocator();
    }
}

Module.php 简化

namespace Application

Class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $serviceManager = $e->getApplication()->getServiceManager();
        $service = $serviceManager->get('Service\From\Other\Module');
    }
}

最佳答案

此处没有足够的数据可以直接帮助您。对于初学者来说,使用函数 ValidateCustomerRegistrationTest->getApplicationServiceLocator() 会更有用。

希望能间接帮助到你。

重构可能会有帮助

当我编写单元测试时,我会从一些个人规则开始。

只测试正在测试的代码。模拟其他一切。无需测试应该已经有自己的测试的东西。

一个函数如何工作应该不重要。只有输入/输出。即使函数的核心发生巨大变化,这也能让您的测试保持可行。

/**
 * @param MvcEventInterface $event
 * @param Service\From\Other\ModuleInterface $service
 *
 * @return boolean
 */
public function onBootstrap(MvcEventInterface $event, Service\From\Other\ModuleInterface $service)
{
  return true;
}

然后在测试类中:

public function testOnBootstrap(){
   $eventMock = $this->getMock(MvcEventInterface::class);
   $serviceMock = $this->getMock(ModuleInterface::class);
   $module = new Module();

   $result = $module->onBootstrap($eventMock, $serviceMock);
   $this->assertTrue($result);
}

* 我显然不知道你要测试什么

当重构不是一个选项时

有两种 mock 类型可以提供帮助,mock 和 mockBuilder 是我马上想到的。看看 PHPUnit documentation for Test Doubles .

$serviceMock = $this->getMockBuilder(ServiceManager::class)
    ->disableOriginalConstructor()
    ->setMethods([
        '__construct',
        'get'
    ])
    ->getMock();

$serviceMock
    ->expects($this->any())
    ->method('get')
    ->will($this->returnValue(
        $this->getMock(ModuleManagerInterface::class)
    ));

祝您好运,如果我们能为您提供更具体的帮助,希望您能告诉我们。我还建议研究面向对象编程的 SOLID 原则。应使您的代码简洁、易于扩展和测试的众多编程原则之一。

关于php - ZF2 - Module.php 中请求的模拟服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34811335/

相关文章:

php - 如何避免 View 中的特殊字符编码?

php - php、perl 和 python 中的 HTTP header

php - 将新项目添加到 PHP 数组中并保存数组的先前大小

php - 编辑 woocommerce 行总数

testing - Loadrunner 11.5 中的 View_State 关联

php - Dotrine 2 和 Zf2 整合

php - Pushd 未在 ubuntu 14.04 上更改 php 中的目录

selenium - 我是否需要在每个使用 Nancy 的测试用例中使用不同的模块?

android - Espresso 测试 Android API 28 模拟器点击问题

php - NoRecordExists 输入过滤器