7

I followed sitepoints Testing Symfony Apps with a Disposable Database Tutorial. I added Fixtures in my Testcase and no Errors appear during SetUp. If i add an Error in the Fixtures (e.g. leaving a nullable=false field empty) the Error is shown, so this code does definitely get executed.

My Config:

doctrine:
    dbal:
        default_connection: memory
        connections:
            memory:
                driver: pdo_sqlite
                memory: true
                charset: UTF8

My SetUp in my WebTestCase:

protected function setUp() {
    parent::setUp();
    self::bootKernel();
    DatabasePrimer::prime(self::$kernel);
    $this->loadFixtures([
        'AppBundle\DataFixtures\ORM\UserData',
        'AppBundle\DataFixtures\ORM\ArtistData'
    ]);
}

Yet, in my WebTestCase it appears that no Tables exist. The output throws a Doctrine Exception saying my table does not exist.

SQLSTATE[HY000]: General error: 1 no such table: my_user_table

If i switch to sql_lite in a file, everything works fine without any other changes:

dbal:
    default_connection: file
    connections:
        file:
            driver:   pdo_sqlite
            path:     %kernel.cache_dir%/test.db
            charset: UTF8

Anyone had success with said tutorial or using a sqlite memory db for unit tests and has any hints or ideas?

Update: I changed my Setup to this to ensure the kernel is not shut down in between. It did not help:

parent::setUp();
$this->client = $this->getClient();
MemoryDbPrimer::prime(self::$kernel);
$this->loadFixtures([
    'AppBundle\DataFixtures\ORM\UserData',
    'AppBundle\DataFixtures\ORM\ArtistData'
]);
Andresch Serj
  • 35,217
  • 15
  • 59
  • 101
  • Have you tried changing the connection name from `memory`, e.g `default_connection: memory` to `default_connection: default` or some other name? it may be that using that reserved word (as it's a property within the connection data itself) is causing an issue. It might be worth posting your fixture file also. – John Joseph Jan 31 '17 at 10:54
  • @JohnJoseph: I tried that, yet it made no difference. My fixtures file is quite large so i'd rather not do that. Also, since it works in sqllte file more, i doubt that my fixtures are the problem. – Andresch Serj Jan 31 '17 at 13:41
  • I still think your kernel somehow gets shutdown/rebooted in between. To find out where, you can add `print("bootKernel() called\n"); debug_print_backtrace();` at the top of the `bootKernel()` function in `vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php` and then run one of the affected test cases. – aferber Feb 03 '17 at 14:54
  • Did you ever find a solution for your problem? I am having a similar problem. – Awemo Feb 16 '17 at 20:22

2 Answers2

6

When you

$client->request(<METHOD>, <URL>);

which calls

Symfony\Bundle\FrameworkBundleClient::doRequest($request)

After the request the kernel is shutdown by default, and your in-memory database is trashed.

If you call

client->disableReboot(); 

in the setup() function of your test, this will behavior is disabled, and you can run the whole suite.

Lighthart
  • 3,648
  • 6
  • 28
  • 47
1

I assume you call createClient() in your test functions. The very first thing that createClient() does is call static::bootKernel(). This basically means that the kernel you booted in your setUp() gets shut down and a new kernel is booted, with a fresh instance of the memory SQLite database.

You can move the createClient() call into your setUp(), replacing the bootKernel(), to avoid this:

class MyTest extends WebTestCase
{
    private $client = null;

    public function setUp()
    {
        $this->client = static::createClient();
        // prime database
    }

    public function testSomething()
    {
        $crawler = $this->client->request('GET', '/');
        // ...
    }
}
aferber
  • 1,121
  • 10
  • 15