Ujian unit OverflowException: Percubaan semula maksimum mencapai 10,000 kali, nilai unik masih tidak ditemui
P粉186897465
P粉186897465 2024-04-06 11:27:39
0
2
509

Jadi saya sedang melakukan beberapa ujian unit sebelum melaksanakan ciri baharu. Saya menjalankan ujian dan ia gagal dengan OverflowException :最大重试次数达到 10000 次,但未找到唯一值 Ini adalah ujian yang saya jalankan.

public function test_job_factory()
    {
        $client = Client::factory()->create();
        $accountHandler = AccountHandler::factory()->create();
        $user = User::factory()->create();

        $this->post('/login', [
            'email' => $user->email,
            'password' => 'password',
        ]);

        $user->givePermissionTo( 'manage jobs' );
        $clientContact = ClientContact::factory()->create();
        $job = Job::factory()->create();

        $this->assertTrue($job->id > 0);
    }

Ralat nampaknya berlaku semasa mencipta kerja itu sendiri. Ujian di atas menguji tumbuhan lain dan berfungsi.

Ini ialah fail JobFactory.php:

<?php

namespace Database\Factories;

use App\Models\AccountHandler;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Job;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Job>
 */
class JobFactory extends Factory
{
    protected $model = Job::class;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'title'              => $this->faker->company(),
            'is_active'          => 1,
            'is_draft'           => 0,
            'client_id'          => $this->faker->unique()->numberBetween(1, Client::count()),
            'account_handler_id' => $this->faker->unique()->numberBetween(1, AccountHandler::count()),
            'eclipse_contact_id' => $this->faker->unique()->numberBetween(1, User::count()),
            'client_contact_id'  => $this->faker->unique()->numberBetween(1, ClientContact::count()),
            'description'        => $this->faker->paragraphs(1),
        ];
    }
}

Dan penghijrahan untuk ini (create_jobs_table.php):

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('jobs', function (Blueprint $table) {
            $table->id('number');
            $table->boolean( 'is_active' )->default(true);
            $table->boolean( 'is_complete' )->default(true);
            $table->string('title', 64)->nullable();
            $table->timestamps();
            $table->foreignId('author')->nullable()->constrained()->references('id')->on('users');
            $table->text('description')->nullable();
            $table->foreignId('client_id')->nullable()->constrained()->references('id')->on('clients');
            $table->foreignId('client_contact_id')->nullable()->constrained()->references('id')->on('client_contacts');
            $table->foreignId('account_handler_id')->nullable()->constrained()->references('id')->on('account_handlers');
            $table->date('expiry_date')->nullable();
            $table->date('artwork_deadline')->nullable();
            $table->date('proof_deadline')->nullable();
            $table->integer('redirect')->nullable();
            $table->boolean( 'is_draft' )->default(true);
            $table->foreignId('eclipse_contact_id')->nullable()->constrained()->references('id')->on('users');
            $table->foreignId('subscription_id')->nullable()->constrained()->references('id')->on('subscriptions');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('jobs');
    }
};

Jadi apa yang salah dan mengapa kitaran ini berlaku? Saya telah menambah data minimum yang diperlukan untuk membuat kerja, jadi tidak pasti apa yang saya hilang.

Terima kasih

*** Edit *** Saya diminta untuk memberikan pautan ke tempat saya mendapati amalan buruk menggunakan unik dan numberBetween, berikut ialah contoh Ini tidak akan berfungsi seperti yang anda cari!

P粉186897465
P粉186897465

membalas semua(2)
P粉442576165

Masalahnya ialah apabila anda cuba mendapatkan 5 nilai antara 1 dan 5 (Termasuk), anda hanya boleh mengambil 4. Nombor ke-5 tidak akan melebihi unique() Pengesahan.

Ini kerana, sebagai contoh, apabila anda menjalankan instance pertama unik

$faker->unique()->numberBetween(1, 20)

Kemudian jalankannya di kilang lain, laravel biasanya memanjangkan contoh sebelumnya (saya rasa), jika itu masuk akal. Tetapi apabila anda lulus benar seperti di bawah

$faker->unique(true)->numberBetween(1, 20)

Ia mula mencari dari 1 hingga 20 semula

Ini menyelesaikan masalah saya.

Oleh itu sentiasa lulus benar dalam unique() contoh

P粉164942791

Saya mengesyorkan mengikuti pendekatan yang didokumenkan untuk menyelesaikan masalah ini. https://laravel.com/docs/9.x/database-test#factoryrelationship

Lihat jadual migrasi anda, ada kemungkinan besar kilang anda tidak akan berfungsi kerana anda menunjukkan perhubungan pada tahap SQL, yang pada asasnya memaksa anda untuk mempunyai rekod dalam jadual berkaitan, jika tidak, SQL akan menimbulkan ralat..

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan