Je fais donc quelques tests unitaires avant d'implémenter de nouvelles fonctionnalités. J'exécute le test et il échoue avec OverflowException :最大重试次数达到 10000 次,但未找到唯一值
C'est le test que j'exécute.
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); }
L'erreur semble se produire lors de la création du travail lui-même. Le test ci-dessus a testé d’autres plantes et fonctionne.
Voici le fichier 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), ]; } }
Et la migration pour cela (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'); } };
Alors, qu’est-ce qui n’a pas fonctionné et pourquoi ce cycle se produit-il ? J'ai ajouté le minimum de données requis pour créer le travail, donc je ne suis pas sûr de ce qui me manque.
Merci
*** Modifier *** On m'a demandé de fournir un lien vers l'endroit où j'ai trouvé la mauvaise pratique consistant à utiliser unique et numberBetween, voici un exemple. Cela ne fonctionnera pas comme vous le recherchez !
Le problème c'est quand on essaie d'obtenir 5 valeurs comprises entre 1 et 5 (Inclus), vous ne pouvez en prendre que 4. Le 5ème chiffre ne dépassera jamais
unique()
Vérification.En effet, par exemple, lorsque vous exécutez la première instance de unique
Ensuite, exécutez-le dans une autre usine, laravel étend généralement l'instance précédente (je suppose), si cela a du sens. Mais quand tu passes vrai comme ci-dessous
Il recommence la recherche de 1 à 20
Cela a résolu mon problème.
Donc, passez toujours vrai dans
unique()
instanceJe recommande de suivre l'approche documentée pour résoudre ce problème. https://laravel.com/docs/9.x/database-test#factoryrelationship
Regardez votre table de migration, il y a de fortes chances que votre usine ne fonctionne pas car vous indiquez la relation au niveau SQL, ce qui vous oblige essentiellement à avoir les enregistrements dans la table associée, sinon SQL générera une erreur.