Introduction

When your are working in a new bundle to share with other projects sometimes you create new service in your bundle with infrastructure dependencies (doctrine, redis, mysql, rabbitMQ, file system …) or include controllers.

In some cases we want to test real behaviour without mocking the dependencies (integration/functional tests) to check if our services are working fine with real dependencies and symfony container.

So to can do functional/integration tests in standalone using the symfony container in our bundle we can add symfony kernel in our Tests folder, we will add FrameworkBundle and own bundle to simulate integration bundle in the final symfony application.

Usage

Create AppKernel.php file inside of Tests folder and add the next code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php

namespace Tests;

use BernardoSecades\FunctionalTestBundle\FunctionalTestBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Kernel;

class AppKernel extends Kernel
{
    /**
     * @return array
     */
    public function registerBundles()
    {
        $bundles = array();

        if (in_array($this->getEnvironment(), array('test'))) {
            $bundles[] = new FrameworkBundle();
            $bundles[] = new NameBundleWeAreWorkingBundle();
        }

        return $bundles;
    }

    /**
     * @param LoaderInterface $loader
     */
    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config_'.$this->getEnvironment().'.yml');

    }

    /**
     * {@inheritdoc}
     */
    public function getCacheDir()
    {
        return sys_get_temp_dir().'/NameBundleWeAreWorkingBundle/cache';
    }

    /**
     * {@inheritdoc}
     */
    public function getLogDir()
    {
        return sys_get_temp_dir().'/NameBundleWeAreWorkingBundle/logs';
    }
}

Create the file config_test.yml with next lines to load your services in test environment:

1
2
3
4
5
6
imports:
    - { resource: "@NameBundleWeAreWorkingBundle/Resources/config/services.yml" }

framework:
    secret: "Three can keep a secret, if two of them are dead."
    test: ~

This configuration will be loaded by AppKernel.php we added before. Check this piece of code from kernel file:

1
2
3
4
5
6
7
8
9
10
11
12
<?php

    // ...

    /**
     * @param LoaderInterface $loader
     */
    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config_'.$this->getEnvironment().'.yml');

    }

And now you can load the class AppKernel in your test putting like first parameter the environment, in this case, environment test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

namespace Tests\Functional;

use Tests\AppKernel;
use BernardoSecades\NameBundleWeAreWorkingBundle\Lib\MyService;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MyTest extends KernelTestCase
{
    /** @var  ContainerInterface */
    protected $container;

    protected function setUp()
    {
        parent::setUp();

        $kernel = new AppKernel('test', true);
        $kernel->boot();
        $this->container = $kernel->getContainer();
    }

    /**
     * @test
     */
    public function checkMyService()
    {
        $myService = $this->container->get('bernardosecades.my_service');

        $this->assertInstanceOf(MyService::class, $myService);
        $this->assertTrue($myService->myAction());
    }
}

See the example in github, functional-tests-standalone-bundle.