owen-it / laravel-auditing

Record the change log from models in Laravel
https://laravel-auditing.com
MIT License
3.05k stars 390 forks source link

Unittest does not work when model Auditable #840

Closed aozen closed 1 year ago

aozen commented 1 year ago
Q A
Bug? yes
New Feature? no
Framework Laravel
Framework version 10.~
Package version 13.5.0
PHP version 8.2.7_1

When testing with pest, Pest does not boot the Laravel application. So we may get the error if we use Auditable on our model. Like:

Test.php

Post::factory()->make();

Post.php

use Auditable;

Run test

./vendor/bin/test

Result:

 RuntimeException 

  A facade root has not been set.

  at vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:350
    346▕     {
    347▕         $instance = static::getFacadeRoot();
    348▕ 
    349▕         if (! $instance) {
  ➜ 350▕             throw new RuntimeException('A facade root has not been set.');
    351▕         }
    352▕ 
    353▕         return $instance->$method(...$args);
    354▕     }

      +2 vendor frames 

  3   [internal]:0
      App\Models\Post::bootAuditable()
      +10 vendor frames 

  14  tests/Feature/Post/Datasets.php:44
      Illuminate\Database\Eloquent\Factories\Factory::make()

It should be pass the booting app.

it goes the bootAuditable.

public static function bootAuditable()
    {
        if (static::isAuditingEnabled()) {
            static::observe(new AuditableObserver());
        }
    }

then

public static function isAuditingEnabled(): bool
    {
        if (App::runningInConsole()) {
            return Config::get('audit.enabled', true) && Config::get('audit.console', false);
        }

        return Config::get('audit.enabled', true);
    }

In isAuditingEnabled function App::runningInConsole()is failing when using non-boot tools. Because App is not loaded yet. Also Config will not be able to load.

Probably there is not perfect way to fix this. For testing purposes manually I added return true/false; in here.

erikn69 commented 1 year ago

Did you try adding on TestCase class

/**
 * @param  \Illuminate\Foundation\Application  $app
 * @return array
 */
protected function getPackageProviders($app)
{
    return [
        \OwenIt\Auditing\AuditingServiceProvider::class,
    ];
}