Maison  >  Questions et réponses  >  le corps du texte

Test unitaire OverflowException : nombre maximum de tentatives atteint 10 000 fois, valeur unique toujours introuvable

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粉186897465P粉186897465219 Il y a quelques jours459

répondre à tous(2)je répondrai

  • P粉442576165

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

    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

    répondre
    0
  • P粉164942791

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

    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.

    répondre
    0
  • Annulerrépondre