vishal
vishal

Reputation: 4083

How to mock Symfony 2 service in a functional test?

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

Upvotes: 31

Views: 33817

Answers (4)

Ramunas Dronga
Ramunas Dronga

Reputation: 128

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

Upvotes: 4

Cyprian
Cyprian

Reputation: 11364

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.

Upvotes: 66

Sven
Sven

Reputation: 70853

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

Upvotes: 6

adam187
adam187

Reputation: 3393

Have you tried ?

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

Upvotes: 0

Related Questions