我最近在学习Symfony 3框架和依赖注入.

我希望您帮助我解决我对使用PHPUnit在Symfony 3中测试服务的方法的疑虑.我有一些担心如何正确地做到这一点.

让我们举一个Service类的例子:

// src/AppBundle/Services/MathService.PHP
namespace AppBundle\Services;

class MathService
{
    public function subtract($a,$b)
    {
        return $a - $b;
    }
}

我看到通常Symfony中的UnitTest类测试控制器.

但是我可以测试像服务这样的独立类(例如包含业务逻辑)而不是控制器?

我知道至少有两种方法可以做到:

1.创建一个测试类,它扩展了PHPUnit_Framework_TestCase,并在此测试类中的某些方法或构造函数中创建了Service对象(与Symfony docs about testing中的内容完全相同)

// tests/AppBundle/Services/MathTest.PHP
namespace Tests\AppBundle\Services;

use AppBundle\Services\MathService;

class MathTest extends \PHPUnit_Framework_TestCase
{
    protected $math;

    public function __construct() {
        $this->math = new MathService();
    }

    public function testSubtract()
    {
        $result = $this->math->subtract(5,3);
        $this->assertEquals(2,$result);
    }
}

2.使用依赖注入将我们的​​Service类作为服务容器.然后创建一个Test Class,它扩展了KernelTestCase以访问内核.它将使我们能够使用来自内核的Container注入我们的服务(基于Symfony docs about testing Doctrine).

服务容器的配置:

# app/config/services.yml
services:
    app.math:
        class: AppBundle\Services\MathService

现在我们的测试类看起来像:

// tests/AppBundle/Services/MathTest.PHP
namespace Tests\AppBundle\Services;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class MathTest extends KernelTestCase
{
    private $math;

    protected function setUp()
    {
        self::bootKernel();

        $this->math = static::$kernel
            ->getContainer()
            ->get('app.math');
    }

    public function testSubtract()
    {
        $result = $this->math->subtract(5,$result);
    }
}

我们选择这种方式有好处.

首先,我们可以通过依赖注入访问控制器和测试中的服务容器.

其次 – 如果将来我们想要更改Service类的位置或更改类的名称 – 与1. case相比 – 我们可以避免更改许多文件,因为我们将至少在services.yml文件中更改路径/名称.

我的问题:

是否有其他方法可以在Symfony 3中测试Service类?哪种方式更好,应该使用?

使用棘手的Symfony 3.4 / 4.0解决方案更新2018年.

这种方法with all its pros/cons is described in this post with code examples.

访问私有服务的最佳解决方案是添加一个编译器通行证,使所有服务公开以进行测试.

1.更新内核

use Symfony\Component\HttpKernel\Kernel;
+use Symplify\PackageBuilder\DependencyInjection\CompilerPass\PublicForTestsCompilerPass;

 final class AppKernel extends Kernel
 {
     protected function build(ContainerBuilder $containerBuilder): void
     {
         $containerBuilder->addCompilerPass('...');
+        $containerBuilder->addCompilerPass(new PublicForTestsCompilerPass());
     }
 }

2.需要或创建自己的编译器通行证

PublicForTestsCompilerPass的位置如下:

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

final class PublicForTestsCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $containerBuilder): void
    {
        if (! $this->isPHPUnit()) {
            return;
        }

        foreach ($containerBuilder->getDeFinitions() as $deFinition) {
            $deFinition->setPublic(true);
        }

        foreach ($containerBuilder->getAliases() as $deFinition) {
            $deFinition->setPublic(true);
        }
    }

    private function isPHPUnit(): bool
    {
        // defined by PHPUnit
        return defined('PHPUNIT_COMPOSER_INSTALL') || defined('__PHPUNIT_PHAR__');
    }
}

要使用此类,只需通过以下方式添加包:

composer require symplify/package-builder

但是,当然,更好的方法是使用自己的类,满足您的需求(您可以迁移Behat进行测试等).

那么你所有的测试都将按预期继续工作!

使用PHPUnit测试Symfony3中的服务/服务容器的优雅方法的更多相关文章

  1. HTML5 播放 RTSP 视频的实例代码

    目前大多数网络摄像头都是通过 RTSP 协议传输视频流的,但是 HTML 并不标准支持 RTSP 流。本文重点给大家介绍HTML5 播放 RTSP 视频的实例代码,需要的朋友参考下吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. 详解如何通过H5(浏览器/WebView/其他)唤起本地app

    这篇文章主要介绍了详解如何通过H5(浏览器/WebView/其他)唤起本地app的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5混合开发app如何升级的方法

    本篇文章主要介绍了H5混合开发app如何升级的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. AmazeUI 折叠面板的实现代码

    这篇文章主要介绍了AmazeUI 折叠面板的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码

    这篇文章主要介绍了HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  7. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. html5唤起app的方法

    这篇文章主要介绍了html5唤起app的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. HTML5拍照和摄像机功能实战详解

    这篇文章主要介绍了HTML5拍照和摄像机功能实战详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. HTML5页面无缝闪开的问题及解决方案

    这篇文章主要介绍了HTML5页面无缝闪开方案,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部