I have a unittests in my Symfony 4 project which show a inconsistent behaviour and I suspect the doctrine caching is responsible for this. So I am looking for a way to disable caching for Unittests.
My current packages/test/doctrine.yaml file for the environment test looks like this:
doctrine:
orm:
auto_generate_proxy_classes: false
metadata_cache_driver:
type: service
id: doctrine.system_cache_provider
query_cache_driver:
type: service
id: doctrine.system_cache_provider
result_cache_driver:
type: service
id: doctrine.result_cache_provider
services:
doctrine.result_cache_provider:
class: Symfony\Component\Cache\DoctrineProvider
public: false
arguments:
- '@doctrine.result_cache_pool'
doctrine.system_cache_provider:
class: Symfony\Component\Cache\DoctrineProvider
public: false
arguments:
- '@doctrine.system_cache_pool'
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.system
If I want to disable any caching in doctrine for tests, is there any cache driver, which is a non-caching dummy? If I leave those entries empty I guess my prod settings or the general settings would be used, which means the results would also be cached. Can I explicitly non-cache? I hope I would not have to write an explicit dummy cache provider, who doesn't cache? This could be a solution, but it looks to me like this should be achieved more easily.
config
\__packages
|
|__ prod
| \__doctrine.yaml
|
|__ dev
| \__doctrine.yaml
|
|__ test
| \__doctrine.yaml
|
\__doctrine.yaml
This is my extended KernelTestCase class:
protected EntityManagerInterface $em;
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();
$kernel = static::createKernel();
$kernel->boot();
$em = $kernel
->getContainer()
->get('doctrine')
->getManager();
$schemaTool = new SchemaTool($em);
$metadata = $em
->getMetadataFactory()
->getAllMetadata();
// Drop and recreate tables for all entities
$schemaTool->dropSchema($metadata);
$schemaTool->createSchema($metadata);
}
protected function setUp(): void
{
parent::setUp();
self::ensureKernelShutdown();
$kernel = static::createKernel();
$kernel->boot();
$this->em = $kernel
->getContainer()
->get('doctrine')
->getManager();
// loads tests data for every tests
$projectDir = $kernel->getProjectDir();
system('php ' . $projectDir . '/bin/console doctrine:fixtures:load --env=test -n -q');
}
....
protected function tearDown(): void
{
parent::tearDown();
if (null !== $this->em) {
$this->em->close();
}
}
cache configuration
No, the settings from prod will never ever be used in test environment. Test uses the configuration from
config/packages/test/
and does fallback to the general settings inconfig/packages/
but never to prod.In a typical setup, general doctrine stuff like mappings are defined in
config/packages/doctrine.yaml
, cache is only defined inconfig/packages/prod/doctrine.yaml
. See official symfony demo applicationYou can also verify your configuration using
bin/console debug:config doctrine --env=test
.test isolation
Your problem is most probably not caused by doctrine cache configuration but by poor isolation of your testcases.
Have a look at Functional Testing of A Doctrine Repository. Symfonys official docs recommend to boot the kernel at
setUp()
and to close the entity manager duringtearDown()
.If that complete isolation is not a feasible approach for you, you will have to debug to find out which testcase causes the breach of isolation. If you pinned the causing testcase you should check its execution path and look out for missing doctrine flushes and for transactions that are left open longer than expected.