Symfony / Doctrine UnitTests with SQLite memory DB
Asked Answered
D

3

11

I'm still working on PHP unit tests for testing my symfony2 controllers. My test classes are derivations of WebTestCase and the tests are doing GET or POST requests to check if everything works fine.

I want to test all underlying layers, but I don't want to mess up my database with the tests. I don't want to use mock-ups, but an in-memory SQLite db, where I can set up a test scenario to check all modifications.

I found a lot of hints how to do this with doctrine 1.x, but they don't work anymore.

So I want something like this:

class BlahblahTest extends WebTestCase {
    public function testXXXYYY() {
        // 1. Setup a new database with SQLite:memory:
        // 2. create the database and all tables according the entities in my project
        $this->createTestScenario(); // 3.
        $crawler = $this->client->request('GET', '/testpage');  // 4.
        // 5. Lots of checks against the database and / or the $crawler data
    }
}

Any chance to get this work?

Decide answered 8/5, 2014 at 9:15 Comment(0)
K
16

I never used in memory sqlite database but for testing i do use a sqlite database that is saved.

For that you should add

# app/config/config_test.yml
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   pdo_sqlite
                path:     %kernel.cache_dir%/test.db

To your test config (for me config_test.yml)

You should be able to change this to in memory according to the documentation

http://docs.doctrine-project.org/projects/doctrine- dbal/en/latest/reference/configuration.html#pdo-sqlite

memory (boolean): True if the SQLite database should be in-memory (non-persistent). Mutually exclusive with path. path takes precedence.

So the config should then be

# app/config/config_test.yml
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   pdo_sqlite
                memory:   true
Keelung answered 8/5, 2014 at 10:57 Comment(4)
Hi, Melvin. First of all, yes, this would work. But changing the soure code it's not my preferred way, because these tests should run automatically on a dedicated server. So the default connection must not be manipulated, but it would be okay to have another second connection. The tests itselves should change their default connection programmatically. There must be a way to do this. Hennes.Decide
Not sure if understand you so this might be a stupid remark. But when you run unittests symfony should use the test env. My example for example runs perfect on a jenkins server and production because the config is only changed when the test env is set the config_test.yml is loaded as an override for config.yml so your config for production would not change.Keelung
Ah, my fault, sorry. I didn't know, that unit tests automatically select the test environment. So I implemented my sqlite driver in the config_test.yml as you mentioned. Works fine. Thank you.Decide
In some special cases you might need to specify memory: true and specifically set path: ":memory:" or you would get complains from Symfony & Doctrine.Verruca
A
9

The accepted answer didn't work for me, because I was using the URL to specify the connection parameters, and although I was setting the driver to pdo_sqliteand memoryto true, Doctrine was still using the url parameter from the root configuration, so I had to overwrite it.

#api/config/packages/test/doctrine.yaml
doctrine:
  dbal:
    url: "sqlite:///:memory:"
Apostrophe answered 15/6, 2019 at 19:10 Comment(0)
D
2

You can easily create entitymanager instance your self. Check this helper class You probably don't have it in symfony 2 but you can use the idea to build your own base testCaseClass and use it when needed. This even does not require to boot kernel.

Downtown answered 5/6, 2017 at 12:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.