29
votes

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

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.

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

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

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);
4

4 Answers

63
votes

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

$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.

5
votes

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

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

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

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

It's easy like that:

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

Have you tried ?

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