laravel-doctrine / orm

A drop-in Doctrine ORM 2 implementation for Laravel 5+ and Lumen
http://laraveldoctrine.org
MIT License
827 stars 179 forks source link

[QUESTION] Seed does not rollback in test #460

Open MP-okui opened 4 years ago

MP-okui commented 4 years ago

I expect a seed rollback.

Package version, Laravel version

Steps to reproduce the behaviour

Using the RefreshDatabase.

<?php

namespace Tests\Traits;

use Illuminate\Contracts\Console\Kernel;
use Illuminate\Foundation\Testing\RefreshDatabase as IlluminateRefreshDatabase;
use Illuminate\Foundation\Testing\RefreshDatabaseState;

trait RefreshDatabase
{
    use IlluminateRefreshDatabase;

    /**
     * Define hooks to migrate the database before and after each test.
     *
     * @return void
     */
    public function refreshDatabase()
    {
        $this->refreshTestDatabase();
    }

    /**
     * Refresh a conventional test database.
     *
     * @return void
     */
    protected function refreshTestDatabase()
    {
        if (! RefreshDatabaseState::$migrated) {
            $this->artisan('doctrine:schema:drop --force');
            $this->artisan('doctrine:schema:create');

            $this->app[Kernel::class]->setArtisan(null);

            RefreshDatabaseState::$migrated = true;
        }

        $this->beginDatabaseTransaction();
    }

    /**
     * Begin a database transaction on the testing database.
     *
     * @return void
     */
    public function beginDatabaseTransaction()
    {
        $connection = $this->app->make('em')->getConnection();
        $connection->beginTransaction();

        $this->beforeApplicationDestroyed(function () use ($connection) {
            $connection->rollBack();
        });
    }
}

Execute seed() with setUp().

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Tests\Traits\RefreshDatabase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

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

        $this->seed();
    }
}

Is it because not using EntityManager in seed()?

eigan commented 4 years ago

Have you confirmed that beginDatabaseTransaction have been called?

MP-okui commented 4 years ago

beginDatabaseTransaction() is being called.

    public function beginDatabaseTransaction()
    {
        $connection = $this->app->make('em')->getConnection();
        $connection->beginTransaction();
        Log::debug('run beginTransaction()');

        $this->beforeApplicationDestroyed(function () use ($connection) {
            $connection->rollBack();
            Log::debug('run rollBack()');
        });
    }
    protected function setUp(): void
    {
        parent::setUp();

        $this->seed();
        Log::debug('run seed()');
    }

    public function testFoo()
    {
        Log::debug('run testFoo()');
        entity(ExampleEntity::class)->create();
    }

    public function testBar()
    {
        Log::debug('run testBar()');
        entity(ExampleEntity::class)->create();
    }

This is the log. I get an error on the second seed() call. (Duplicate primary key) The created entity was rolled back.

[2020-09-30 17:29:04] testing.DEBUG: run beginTransaction()  
[2020-09-30 17:29:04] testing.DEBUG: run seed()  
[2020-09-30 17:29:04] testing.DEBUG: run testFoo()  
[2020-09-30 17:29:04] testing.DEBUG: run rollBack()  
[2020-09-30 17:29:04] testing.DEBUG: run beginTransaction()  
[2020-09-30 17:29:05] testing.DEBUG: run rollBack()  
eigan commented 3 years ago

Did you manage to figure out what the problem was @MP-okui ?

MP-okui commented 3 years ago

I solved it by running seed() with refreshTestDatabase(). Has there been an update for laravel-doctrine/orm about this problem?

    protected function refreshTestDatabase()
    {
        if (! RefreshDatabaseState::$migrated) {
            $this->artisan('doctrine:schema:drop --force');
            $this->artisan('doctrine:schema:create');

            // added
            $this->seed();

            $this->app[Kernel::class]->setArtisan(null);

            RefreshDatabaseState::$migrated = true;
        }

        $this->beginDatabaseTransaction();
    }
eigan commented 3 years ago

Has there been an update for laravel-doctrine/orm about this problem?

Not that I am aware of.

I am not able to figure the problem with the information currently available. If you want help fixing this then I would be grateful for a reproducible test (either a new test-repo or a testcase here).