laravel-doctrine / orm

An integration library for Laravel and Doctrine ORM
MIT License
828 stars 178 forks source link

Unable to locate factory with name [default] [App\Entities\User] #645

Open AtteR opened 2 weeks ago

AtteR commented 2 weeks ago

If you have a question, and not a bug or proposal, post in the discussions. https://github.com/laravel-doctrine/orm/discussions

laravel-doctrine/orm version & Laravel version

"require": {
    "php": "^8.2",
    "gedmo/doctrine-extensions": "^3.17",
    "laravel-doctrine/extensions": "^2.0",
    "laravel-doctrine/migrations": "^3.3",
    "laravel-doctrine/orm": "^3.0",
    "laravel/framework": "^11.9",
    "laravel/tinker": "^2.9"
},
"require-dev": {
    "fakerphp/faker": "^1.23",
    "laravel/pail": "^1.1",
    "laravel/pint": "^1.13",
    "laravel/sail": "^1.26",
    "mockery/mockery": "^1.6",
    "nunomaduro/collision": "^8.1",
    "phpunit/phpunit": "^11.0.1"
},

Expected behaviour

When running factories (either in tests or seeder), the factories in database/factories should be properly located.

Actual behaviour

When running this example seeder:

<?php

namespace Database\Seeders;

use App\Entities\User;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        entity(User::class)->create();
    }
}

with php artisan db:seed following error happens:

InvalidArgumentException

Unable to locate factory with name [default] [App\Entities\User]

at vendor/laravel-doctrine/orm/src/Testing/FactoryBuilder.php:205 201▕ */ 202▕ protected function makeInstance(array $attributes = []): mixed 203▕ { 204▕ if (! isset($this->definitions[$this->class][$this->name])) { ➜ 205▕ throw new InvalidArgumentException('Unable to locate factory with name [' . $this->name . '] [' . $this->class . ']'); 206▕ } 207▕ 208▕ $definition = call_user_func($this->definitions[$this->class][$this->name], $this->faker, $attributes); 209▕

Steps to reproduce

  1. Fresh install of L11 with packages gedmo/doctrine-extensions laravel-doctrine/extensions laravel-doctrine/migrations laravel-doctrine/orm

  2. Add entity, for example:

<?php

namespace App\Entities;

use App\Traits\MustVerifyEmail;
use DateTime;
use DateTimeImmutable;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract;
use LaravelDoctrine\ORM\Notifications\Notifiable;

#[ORM\Entity]
#[ORM\Table(name: "users")]
class User implements Authenticatable, CanResetPasswordContract, MustVerifyEmailContract
{
    use CanResetPassword, \LaravelDoctrine\ORM\Auth\Authenticatable, MustVerifyEmail, Notifiable;

    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: "AUTO")]
    #[ORM\Column(type: 'integer')]
    protected int $id;

    #[ORM\Column(type: 'string', length: 255)]
    protected string $name;

    #[ORM\Column(type: 'string', length: 255, unique: true)]
    protected string $email;

    #[ORM\Column(type: 'datetime', nullable: true)]
    protected ?DateTime $emailVerifiedAt = null;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    #[Gedmo\Timestampable]
    protected ?DateTimeImmutable $createdAt = null;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    #[Gedmo\Timestampable]
    protected ?DateTimeImmutable $updatedAt = null;

    public function __construct() {}

    public function getId(): int
    {
        return $this->id;
    }

    public function getKey(): int
    {
        return $this->getId();
    }

    public function setId(int $id): void
    {
        $this->id = $id;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function getEmail(): string
    {
        return $this->email;
    }

    public function setEmail(string $email): void
    {
        $this->email = $email;
    }

    public function getEmailVerifiedAt(): ?DateTime
    {
        return $this->emailVerifiedAt;
    }

    public function setEmailVerifiedAt(?DateTime $emailVerifiedAt): void
    {
        $this->emailVerifiedAt = $emailVerifiedAt;
    }

    public function getCreatedAt(): DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function getUpdatedAt(): DateTimeImmutable
    {
        return $this->updatedAt;
    }
}
  1. Create factory to database/factories/UserFactory.php
<?php

use Faker\Generator as Faker;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

$factory->define(App\Entities\User::class, function (Faker $faker, array $attributes) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => Hash::make('password'),
        'emailVerifiedAt' => $attributes['emailVerifiedAt'] ?? new DateTime,
        'rememberToken' => Str::random(10),
    ];
});
  1. Create seeder:
<?php

namespace Database\Seeders;

use App\Entities\User;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        entity(User::class)->create();
    }
}
  1. Run command > php artisan db:seed

The app works normally, no bugs or errors there but the factories are not currently located for some reason.

Thanks!