Search code examples
laravelsqlitephpunitlaravel-5.6in-memory-database

Use in-memory SQLite in Laravel PHPUnit test


I'm trying to get a Laravel project running at my new work. The developer who left didn't specify how to get the code up and running in the handover document and no-one else knows either.

The SQLite database is created with :memory:, and php artisan migrate works without errors.

...
Migrating: 2016_06_01_000004_create_oauth_clients_table
Migrated:  2016_06_01_000004_create_oauth_clients_table
...

The method beginDatabaseTransaction() in the trait (standard Laravel code) is being executed, but none of the tables exist afterwards. It's as if the database is being created but the migration is not being executed.

<?php

namespace Illuminate\Foundation\Testing;

trait DatabaseTransactions
{
    /**
     * Handle database transactions on the specified connections.
     *
     * @return void
     */
    public function beginDatabaseTransaction()
    {
        $database = $this->app->make('db');

        foreach ($this->connectionsToTransact() as $name) {
            $database->connection($name)->beginTransaction();
        }

        $this->beforeApplicationDestroyed(function () use ($database) {
            foreach ($this->connectionsToTransact() as $name) {
                $connection = $database->connection($name);

                $connection->rollBack();
                $connection->disconnect();
            }
        });
    }

Test code (the last shown instruction fails):

<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Laravel\Passport\ClientRepository;

class PassportTest extends TestCase
{
    use DatabaseTransactions;

    public function test_basic_oauth_token_authentication(){
      $clientRepository = new ClientRepository();
      $client = $clientRepository->createPersonalAccessClient(
          null, 'Test Personal Access Client', $this->baseUrl
      );

Command line:

vendor/bin/phpunit tests/Feature/PassPortTest

Error message:

Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such table: oauth_clients
Caused by  
Doctrine\DBAL\Driver\PDOException: SQLSTATE[HY000]: General error: 1 no such table: oauth_clients
Caused by
PDOException: SQLSTATE[HY000]: General error: 1 no such table: oauth_clients

How can I ensure that the tables have been created as part of each test?


Solution

  • Use the RefreshDatabase trait instead of the DatabaseTransactions trait (they have conflicts if you try to use both in the same class).

    See the documents about resetting the database after each test.