naghal
naghal

Reputation: 716

How to use the RefreshDatabase trait with a Sql server database?

I am trying to use a real Sql Server connection to run my php unit test in Laravel because SqLite does not have the function I am trying to test. The database name is "Test" and the connection details have all been added to database.php.

I have changed my phpunit.xml env variables to refer to the new test database.

    <env name="DB_CONNECTION" value="test_sqlserver"/>
    <env name="DB_DATABASE" value="Test"/>

Now, when I try to run a simple test with a class that use the RefreshDatabase trait, or even the DatabaseMigrations trait, it result in the following error: Symfony\Component\Console\Exception\InvalidOptionException: The "--drop-views" option does not exist.

It can be reproduced with the following test:

<?php

namespace Tests\Unit\Actions;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class GetResourcesExceedingHoursByPayPeriodWeeksActionTest extends TestCase
{
    use RefreshDatabase;

    protected $dropViews = false;

    /** @test */
    public function it_can_get_resources_exceeding_hours_by_pay_period_weeks()
    {

    }

}

Edit The solution bellow proposed by Daniel did not solve the issue. Inspiring from that however, I added the following method:

 protected function migrateFreshUsing()
 {
    $seeder = $this->seeder();
    
    return array_merge([
        //    '--drop-views' => $this->shouldDropViews(),
        //    '--drop-types' => $this->shouldDropTypes(),
        ],
        // $seeder ? ['--seeder' => $seeder] : ['--seed' => $this->shouldSeed()]
    );
}

It resolved the error, however, now phpunit does not output any result. (I added a simple assertion $this->assertTrue(false);)

Full class code:

<?php

namespace Tests\Unit\Actions;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class GetResourcesExceedingHoursByPayPeriodWeeksActionTest extends TestCase
{
    use RefreshDatabase;

    protected $dropViews = false;

    protected function migrateFreshUsing()
    {
       $seeder = $this->seeder();
   
       return array_merge([
           //    '--drop-views' => $this->shouldDropViews(),
           //    '--drop-types' => $this->shouldDropTypes(),
           ],
           //$seeder ? ['--seeder' => $seeder] : ['--seed' => $this->shouldSeed()]
       );
   }

    /** @test */
    public function it_can_get_resources_exceeding_hours_by_pay_period_weeks()
    {
        $this->assertTrue(false);
    }

}

Console output of phpunit

Edit 13:00

Adding the new tag in the phpunit.xml did not help to add output to the console. However, I found the line causing the issue, as when it is commented, phpunit does output to the console. To test correctly, I extended from the base TestCase class instead of the one shown above.

Then I added $this->seed(DatabaseSeeder::class); as the first line of my test, which resulted in no output. Commenting it would allow phpunit to output, but obviously, the test would work with the dummy assertion, but not with anything that requires seeding.

With further investigation it seems that the issue is caused by 3 seeders that uses a third party package to seed from a csv file. Every other seeder run fine.

I will keep investigating this path and update my question with the solution.

How can I test using a real Sql server database?

Upvotes: 2

Views: 482

Answers (1)

Daniel Haven
Daniel Haven

Reputation: 346

I'm not familiar enough with using SqlServer with Laravel, but this answer might be what you're looking for.

It's often the case that there's a default method that doesn't mesh well with a specific use case.

Writing this into your Tests\TestCase class might solve the issue.

/**
 * Refresh a conventional test database.
 *
 * @return void
 */
protected function refreshTestDatabase()
{
    if (! RefreshDatabaseState::$migrated) {
        $this->artisan('migrate:fresh', [
            '--drop-views' => $this->shouldDropViews(),
            '--drop-types' => $this->shouldDropTypes(),
        ]);

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

        RefreshDatabaseState::$migrated = true;
    }

    $this->beginDatabaseTransaction();
}

EDIT Jan 13 2023 12:23 pm

For the PhpUnit not outputting anything issue, reference this answer. Let me know in the comments if you don't get an explicit error displayed on your terminal.

Upvotes: 1

Related Questions