Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

leknoppix's avatar

Help Needed for Writing Unit Tests for Laravel Plugin Migrations

Good evening everyone,

I'm reaching out here to seek your assistance. I am currently working on coding my very first Laravel plugin. To gain experience and ensure my code is 100% functional, I want to start on a solid foundation by implementing static analysis and, most importantly, unit tests.

You can find my plugin, which is still under development, at the following link: https://github.com/leknoppix/YoutubeUpload/tree/24-gestion-de-lupload-dune-vid%C3%A9o

Progress has been slow since I'm only able to work on it in my free time.

I have been struggling for several hours to figure out how to write unit tests for my migrations. I have attempted several tests, and although they do not fail, I can't seem to achieve proper coverage. You can find these tests in the repository linked above.

<?php

namespace Leknoppix\YoutubeUpload\Tests\Unit\Database\Migrations;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schema;
use Leknoppix\YoutubeUpload\Tests\TestCase;

class MigrationTest extends TestCase
{
    use RefreshDatabase;

    public function testDownMigration()
    {
        Artisan::call('migrate');

        $this->assertTrue(Schema::hasTable('youtubeupload_videos'));

        Artisan::call('migrate:rollback');

        $this->assertFalse(Schema::hasTable('youtubeupload_videos'));
    }

    public function test_creation_all_database_tables()
    {
        Artisan::call('migrate');
        $this->assertTrue(Schema::hasTable('youtubeupload_videos'));
        $this->assertTrue(Schema::hasTable('youtubeupload_channel'));
        $this->assertTrue(Schema::hasTable('youtubeupload_access_tokens'));
    }

    public function test_the_youtubeupload_access_tokens_table_is_created_successfully()
    {
        // Vérifiez que la table existe
        $this->assertTrue(Schema::hasTable('youtubeupload_access_tokens'));

        // Vérifiez que les colonnes attendues existent
        $columns = Schema::getColumnListing('youtubeupload_access_tokens');
        $expectedColumns = ['id', 'channel_id', 'access_token', 'created_at', 'updated_at']; 
        foreach ($expectedColumns as $expectedColumn) {
            $this->assertTrue(in_array($expectedColumn, $columns), "$expectedColumn does not exist in youtubeupload_access_tokens table");
        }
    }
}

Could someone explain how I might accomplish this or if, in this case, it might not be necessary?

If you notice any errors and/or unconventional practices in my code, please don't hesitate to let me know.

Thank you in advance.

0 likes
2 replies
Tray2's avatar

I would not write tests for migrations, I would write a happy path feature test where I create a record and then make sure that all the values are there.

Something like this.

it('it shows all the information about a book', function () {
    $book = Book::factory()
        ->has(Author::factory())
        ->for($genre = Genre::factory()->create([
            'media_type_id' => $this->mediaTypeId,
        ]))
        ->for($format = Format::factory()->create([
            'media_type_id' => $this->mediaTypeId,
        ]))
        ->for($series = Series::factory()->create())
        ->for($publisher = Publisher::factory()->create())
        ->create();
    $author = $book->authors->first();

    get(route('books.show', $book))
    ->assertOk()
    ->assertSeeText([
        $book->title,
        $book->isbn,
        $book->part,
        $book->blurb,
        $book->published_year,
        $author->first_name,
        $author->last_name,
        $genre->name,
        $format->name,
        $series->name,
        $publisher->name,
    ]);
});
leknoppix's avatar

I have managed to do my tests on factories and seeders, but I can't understand if there is any usefulness and if so, how to proceed. Thank you for taking the time to respond to me.

<?php

namespace Leknoppix\YoutubeUpload\Tests\Unit\Database\Factory;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Leknoppix\YoutubeUpload\Database\Factories\YoutubeUploadAccessTokenFactory;
use Leknoppix\YoutubeUpload\Models\YoutubeUploadAccessToken;
use Leknoppix\YoutubeUpload\Tests\TestCase;

class YoutubeUploadAccessTokenFactoryTest extends TestCase
{
    use RefreshDatabase;

    public function test_access_token_factory()
    {
        $token = YoutubeUploadAccessToken::factory()->make();

        $this->assertNotNull($token->getAttribute('channel_id'));
        $this->assertNotEmpty($token->getAttribute('access_token'));
    }

    /** @test */
    public function it_can_produce_valid_definition_for_youtube_upload_access_token_model()
    {
        $youtubeAccessTokenFactory = new YoutubeUploadAccessTokenFactory();
        $definition = $youtubeAccessTokenFactory->definition();

        $this->assertArrayHasKey('channel_id', $definition);
        $this->assertArrayHasKey('access_token', $definition);
        $this->assertTrue(is_string($definition['access_token']));
    }
}

Please or to participate in this conversation.