搜尋

首頁  >  問答  >  主體

Unit測試OverflowException:達到最大重試次數10000次,仍未找到唯一值

因此,在實現新功能之前,我正在進行一些單元測試。我執行測試,但失敗並出現 OverflowException :最大重試次數達到 10000 次,但未找到唯一值 這是我正在執行的測試。

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);
    }

該錯誤似乎是在建立作業本身時發生的。上面的測試測試了其他工廠並且正在工作。

這是 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),
        ];
    }
}

以及為此的遷移(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');
    }
};

那麼出了什麼問題,為什麼會出現這個循環?我已經添加了創建作業所需的最少數據,因此我不知道我錯過了什麼。

謝謝

*** 編輯 *** 我被要求提供一個鏈接,指向我發現使用unique 和numberBetween 的不好做法的地方,這裡是一個示例Laravel 工廠錯誤“最大重試次數達到10000 次,但沒有找到唯一值”,當我使用unique Faker 方法時,這不會像你那樣工作期待!

P粉186897465P粉186897465271 天前535

全部回覆(2)我來回復

  • P粉442576165

    P粉4425761652024-04-07 10:22:31

    問題是當你嘗試取得 1 到 5 之間的 5 個值時 (含),你只能取4個。第5個數字永遠不會超過 unique() 驗證。

    這是因為,例如,當您執行 unique 的第一個實例時

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

    然後在另一個工廠中運行它,laravel 通常會擴展前一個實例(我猜),如果這有意義的話。 但是當你像下面這樣傳遞true

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

    它再次開始從 1 到 20 搜尋

    這解決了我的問題。

    因此總是在 unique() 實例中傳遞 true

    回覆
    0
  • P粉164942791

    P粉1649427912024-04-07 00:42:24

    我建議遵循文件方法來解決此問題。 https://laravel.com/docs/9.x/database-測試#工廠關係

    #看看你的遷移表,你的工廠很有可能無法運作,因為你在SQL層級上指示了關係,這基本上會迫使你在相關表中擁有記錄,否則SQL會拋出錯誤..

    回覆
    0
  • 取消回覆