Test unitaire OverflowException : nombre maximum de tentatives atteint 10 000 fois, valeur unique toujours introuvable
P粉186897465
P粉186897465 2024-04-06 11:27:39
0
2
478

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 !

P粉186897465
P粉186897465

répondre à tous(2)
P粉442576165

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

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

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

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

Il recommence la recherche de 1 à 20

Cela a résolu mon problème.

Donc, passez toujours vrai dans unique() instance

P粉164942791

Je 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.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal