php 如何在功能测试中模拟 Symfony 2 服务?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19726281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 19:56:18  来源:igfitidea点击:

How to mock Symfony 2 service in a functional test?

phpunit-testingsymfonymockingphpunit

提问by vishal

I have symfony service which uses redis connection in some methods but not in all methods.

我有 symfony 服务,它在某些方法中但不是在所有方法中都使用 redis 连接。

class ServiceA
{
    private $redis;

    public function __construct($redis)
    {
        $this->redis = $redis;
    }

    public function getRequest($param1, $param2)
    {
    $result = $param1+ $param2;
        return $request;
    }

    .. other methods which use $redis connection
}

I am writing functional test for the code which use only getRequest method (this method does not need redis connection) but as the constructor takes the connection as an argument, when I run test it tried to connect redis server.

我正在为仅使用 getRequest 方法(此方法不需要 redis 连接)的代码编写功能测试,但由于构造函数将连接作为参数,当我运行测试时,它尝试连接 redis 服务器。

How can I write mock service which does not use redis connection at all and ignore original constructor.

如何编写完全不使用 redis 连接并忽略原始构造函数的模拟服务。

I am trying approach mentioned below but no success. It still tries to connect redis eventhough I have disabled original constructor.

我正在尝试下面提到的方法,但没有成功。即使我禁用了原始构造函数,它仍然尝试连接 redis。

http://blog.lyrixx.info/2013/04/12/symfony2-how-to-mock-services-during-functional-tests.html

http://blog.lyrixx.info/2013/04/12/symfony2-how-to-mock-services-during-functional-tests.html

$serviceA = $this->getMockBuilder('ServiceA')
    ->disableOriginalConstructor()
    ->getMock();

static::$kernel->getContainer()->set('my_bundle.service.a', $serviceA);

回答by Cyprian

After you create ServiceAmock, you need to pass it to client's container (not the one from kernel's because client object builds its own kernel). Try this:

创建ServiceA模拟后,您需要将其传递给客户端的容器(不是来自内核的容器,因为客户端对象构建了自己的内核)。尝试这个:

$client = self::createClient();

$serviceA = $this->getMockBuilder('ServiceA')
    ->disableOriginalConstructor()
    ->getMock();

$client->getContainer()->set('my_bundle.service.a', $serviceA);

Pay attention, that you must inject this mocked service every time you make a request. It's because the client rebuilds kernel between each two requests.

请注意,每次发出请求时都必须注入此模拟服务。这是因为客户端在每两个请求之间重建内核。

回答by Sven

You should not mock your tested class, you should mock the Redis class and inject it.

你不应该模拟你的测试类,你应该模拟 Redis 类并注入它。

If Redis isn't used for this test, you need not even configure the mock.

如果此测试未使用 Redis,则您甚至不需要配置模拟。

$redis = $this->getMockBuilder('Redis')->disableOriginalConstructor()->getMock();
$serviceA = new ServiceA($redis);

回答by Ramunas Dronga

There is special tool which takes care of mocked services - https://github.com/ramunasd/symfony-container-mocks

有一个特殊的工具可以处理模拟服务 - https://github.com/ramunasd/symfony-container-mocks

It's easy like that:

就这么简单:

$service = static::$kernel->getContainer()->prophesize('my.custom.service');

回答by adam187

Have you tried ?

你有没有尝试过 ?

$serviceA = $this->getMock('ServiceA', array('getRequest'), array(), '', false);