In memory sqlite always empty despite setup
Asked Answered
P

2

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'
]);
Pyongyang answered 27/1, 2017 at 11:6 Comment(4)
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.Margretmargreta
@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.Pyongyang
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.Esta
Did you ever find a solution for your problem? I am having a similar problem.Donaldson
T
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.

Transcribe answered 30/10, 2017 at 17:1 Comment(2)
$this->client->disableReboot(); this was the missing piece for me - preventing the TableNotFoundException I was getting.Pehlevi
client->disableReboot(); ... manno ... 4 hours digged around for this. Thanks!Upheaval
E
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', '/');
        // ...
    }
}
Esta answered 2/2, 2017 at 19:6 Comment(2)
Good Point, yet, this is already done in my Tests: protected function setUp() { parent::setUp(); $this->client = $this->makeClient(); ...Pyongyang
Maybe you should show us one of your test functions.Esta

© 2022 - 2024 — McMap. All rights reserved.