1

I am new to writing tests and I was wondering if what I am doing here is correct.

Basically I wanna write a test to check if the settings are correct but I use a record straight from my database.

Everything works great but I was wondering what if my database is empty? This test will never work

So what is best practice here?

my test:

/** @test */
public function settings_for_ftp_flysytem_is_correct_test()
{
    $clientSettings = Client::where('category', 'ftp')->first()->settings()->get();

    $this->assertArrayHasKey('host', $clientSettings);
    $this->assertArrayHasKey('username', $clientSettings);
    $this->assertArrayHasKey('password', $clientSettings);
    $this->assertArrayHasKey('port', $clientSettings);
    $this->assertArrayHasKey('root', $clientSettings);
}
michael
  • 421
  • 6
  • 21

1 Answers1

1

I reckon the easiest solution is to use DatabaseTransactions trait and model factories. It is always a good idea to generate test data for every test case.

<?php
// ClientFactory.php

use Faker\Generator;

$factory::define(App\Setting::class, function (Generator $faker) {
    return [...];
});
<?php
// SettingFactory.php

use Faker\Generator;

$factory::define(App\Setting::class, function (Generator $faker) {
    return [...];
});
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseTransactions;

use App\Client;
use App\Setting;

class SettingsTest extends TestCase
{
    use DatabaseTransactions;

    public function test_client_has_settings()
    {
        // 1. Arrange.
        $client = factory(Client::class)->create();
        $settings = factory(Setting::class, 2)->create();
        $client->settings()->saveMany($settings);

        // 2. Act.
        $response = $this->getJson("/clients/{$client->id}/settings");

        // 3. Assert.
        $response->assertJson([...]);
    }
}

The above code is an example. For more info, pls check the following resources:Laravel Docs, Build a Forum with Laravel, Test-Driven Laravel.

Kevin Bui
  • 2,754
  • 1
  • 14
  • 15
  • the settings is just a property in the client model I used this package for that: https://laravel-news.com/laravel-model-settings – michael Jul 26 '19 at 12:17