首页 > 解决方案 > 无法在 PHPUnit 测试中找到名称为 [default] [App\Grade] 的工厂,但在 Tinker 中工作

问题描述

我刚刚开始了一个新的 Laravel 项目并创建了一个模型工厂:

<?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(),
    ];
});

对于以下型号:

<?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');
    }
}

当我从 调用它时php artisan tinker,将创建模型:

>>> $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),
     },
   }

但是当我从我的测试中调用它时:

<?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();
        }
    }

我收到以下错误:

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

这是一个全新的 Laravel 6 安装,所以我想不出为什么会这样。我已经尝试过跑步composer dump-autoloadphp artisan cache:clear但没有运气。

我的PHPUnit.xml文件看起来像:

<?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>

标签: phplaravelphpunitfactory

解决方案


单元测试正在使用use PHPUnit\Framework\TestCase;

但功能测试使用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();
        }
    }

功能测试在 Laravel 启动后运行。我相信PHPUnit\Framework\TestCase在 Laravel 启动之前运行。


推荐阅读