laravel-modules icon indicating copy to clipboard operation
laravel-modules copied to clipboard

Problem with Factory creation

Open AlexisVS opened this issue 4 months ago • 0 comments

Versions:

  • laravel-modules Version: 11.1.4
  • Laravel Version: 11.9
  • PHP Version: 8.3

Description:

When I make a factory and I want to run a test there is a problem.

Steps To Reproduce:

  • make a factory
  • call the factory in a test

Console error:

   FAILED  Modules\Financial\Tests\Feature\FinancialServiceTest > service can deposit funds                                                                                                                                                   Error   
  Class "Database\Factories\Modules\Financial\Models\AccountFactory" not found

  at vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:833
    829▕     public static function factoryForModel(string $modelName)
    830▕     {
    831▕         $factory = static::resolveFactoryName($modelName);
    832▕
  ➜ 833▕         return $factory::new();
    834▕     }
    835▕
    836▕     /**
    837▕      * Specify the callback that should be invoked to guess factory names based on dynamic relationship names.

      +2 vendor frames 
  3   Modules/Financial/tests/Feature/FinancialServiceTest.php:29

I've resolved the solution with :

creating app/Providers/ModulesServiceProvider.php file with:

<?php
declare(strict_types=1);

namespace App\Providers;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;

class ModulesServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {

    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        // For each Factory inside config('modules.namespace')/*/database/factories
        // call the factory att Modules\*\Database\Factories and not at Database\Factories\Modules\*\Database\Factories\ModuleName + Factory
        Factory::guessFactoryNamesUsing(function (string $modelName) {
            if (str_starts_with($modelName, config('modules.namespace', 'Modules\\'))) {

                // get the first part of the string before Models and get the last part of the string for the model name
                $modelNameArr = explode('\\', $modelName);

                // get index of Models
                $index = array_search('Models', $modelNameArr);

                // get the first part of the string before Models index value
                $moduleNamespace = implode('\\', array_slice($modelNameArr, 0, $index));

                // get the last part of the string for the model name
                $modelNameModel = end($modelNameArr);

                return $moduleNamespace . '\\Database\\Factories\\' . $modelNameModel . 'Factory';
            }

            return 'Database\\Factories\\' . Str::afterLast($modelName, '\\') . 'Factory';
        });
    }
}

AlexisVS avatar Oct 12 '24 12:10 AlexisVS