Alex
Alex

Reputation: 3072

Unable to locate factory with name [default] [App\Grade] in PHPUnit tests but working in Tinker

I've just started a new Laravel project and created a model factory:

<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Model;
use Faker\Generator as Faker;

$factory->define(\App\Grade::class, function (Faker $faker) {
    return [
        'grade_number' => 1,
        'valid_from' => \Carbon\Carbon::now(),
    ];
});

For the following model:

<?php

namespace App;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;

class Grade extends Model
{
    /**
     * Scope a query to select the latest date entry for each grade
     *
     * @param $query
     *
     * @return mixed
     */
    public function scopeCurrent($query)
    {
        // This selects the latest set of grades from the table with a current start date

        return $query->where('valid_from', '<', Carbon::now())->orderByDesc('valid_from');
    }
}

When I call this from php artisan tinker, the model is created:

>>> $grade = factory(\App\Grade::class)->make();
=> App\Grade {#3057
     grade_number: 1,
     valid_from: Carbon\Carbon @1576082185 {#3050
       date: 2019-12-11 16:36:25.169212 UTC (+00:00),
     },
   }

But when I call this from my test:

<?php

    namespace Tests\Unit;

    use App\Grade;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use PHPUnit\Framework\TestCase;

    class GradeTest extends TestCase
    {

        use RefreshDatabase;

        /** @test */
        public function it_knows_its_latest_grades()
        {
            $grade = factory(Grade::class)->make();
        }
    }

I get the following error:

InvalidArgumentException : Unable to locate factory with name [default] [App\Grade].

This is a fresh Laravel 6 installation, so I can't think of why this is happening. I've already tried to run composer dump-autoload and php artisan cache:clear with no luck.

My PHPUnit.xml file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
         backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>

        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <server name="APP_ENV" value="testing"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <server name="DB_CONNECTION" value="sqlite"/>
        <server name="DB_DATABASE" value=":memory:"/>
        <server name="MAIL_DRIVER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="SESSION_DRIVER" value="array"/>
    </php>
</phpunit>

Upvotes: 0

Views: 92

Answers (2)

Sharif Mohammad Eunus
Sharif Mohammad Eunus

Reputation: 834

Unit tests are using use PHPUnit\Framework\TestCase;

but features test uses use Tests\TestCase;

<?php

    namespace Tests\Unit;

    use App\Grade;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use PHPUnit\Framework\TestCase;

    class GradeTest extends TestCase
    {

        use RefreshDatabase;

        /** @test */
        public function it_knows_its_latest_grades()
        {
            $grade = factory(Grade::class)->make();
        }
    }

Feature test runs after Laravel boot up. I believe PHPUnit\Framework\TestCase runs before Laravel boots up.

Upvotes: 1

bambamboole
bambamboole

Reputation: 587

I had a same issue a while ago and two suggestions:

  1. Clear all caches
  2. run composer dumpautoload

Currently I have no option to rebuild this but maybe this helps.

Upvotes: 0

Related Questions