Build a Laravel App With TDD – Episode 4, InvalidArgumentException: Unable to locate factory with name [default] [App\Project]

huangapple go评论79阅读模式
英文:

Build a Laravel App With TDD - Episode 4, InvalidArgumentException: Unable to locate factory with name [default] [App\Project]

问题

I am deep in bug town here, can anyone help?
我深陷在错误之中,有人能帮忙吗?

I am following the tutorial line by line and have got as far as the unit test in the episode:
我正在逐行按照教程操作,已经进行到了该集的单元测试部分:

I get the error:
我遇到了以下错误:

>1) Tests\Unit\ProjectTest::test_it_has_a_path
>1) Tests\Unit\ProjectTest::test_it_has_a_path

>InvalidArgumentException: Unable to locate factory with name [default] [App\Project].
>InvalidArgumentException: 找不到名为 [default] 的工厂 [App\Project]。

Some info:
一些信息:

  • The unit test is the second test in the video (starts @ 4:18), my code works fine for the first (feature) test, and the factory function works fine in tinker.
  • 单元测试是视频中的第二个测试(从 4:18 开始),我的代码在第一个(功能)测试中运行正常,并且工厂函数在 tinker 中也正常工作。
  • I have tried all kinds of different filepaths for 'App\Project', and also tried static Project::class type references.
  • 我尝试了各种不同的文件路径来表示 'App\Project',并且也尝试了静态的 Project::class 类型引用。
  • My phpunit didn't run tests unless I prefixed the word 'test', even when filtering to the exact test name, so I believe this may be due to an underlying phpunit version difference.
  • 我的 phpunit 只有在我在测试名称前加上 'test' 时才运行测试,即使在精确的测试名称过滤时也是如此,所以我认为这可能是由于底层 phpunit 版本差异导致的。

My unit test:
我的单元测试:

namespace Tests\Unit;

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

class ProjectTest extends TestCase
{

    use RefreshDatabase;

    public function test_it_has_a_path()
    {
        $project = factory('App\Project')->create();
        $this->assertEquals('/project/' . $project->id, $this->path());
    }
}

My Project factory
我的 Project 工厂:

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

use App\Project;
use Faker\Generator as Faker;

$factory->define(Project::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'description' => $faker->sentence
    ];
});

My show method
我的 show 方法:

public function show(Project $project)
{
    return view('projects.show', compact('project'));
}

My route
我的路由:

Route::get('projects/{project}', 'ProjectsController@show');

and the working feature test (for reference)
以及工作的功能测试(供参考)

public function test_a_user_can_view_a_project()
{
    $this->withoutExceptionHandling();
    $project = factory('App\Project')->create();

    $this->get("/projects/" . $project->id)
        ->assertSee($project->title)
        ->assertSee($project->description);
}
英文:

I am deep in bug town here, can anyone help?
I am following the tutorial line by line and have got as far as the unit test in the episode:
https://laracasts.com/series/build-a-laravel-app-with-tdd/episodes/4

I get the error:
>1) Tests\Unit\ProjectTest::test_it_has_a_path
>InvalidArgumentException: Unable to locate factory with name [default] [App\Project].

Some info:

  • The unit test is the second test in the video (starts @ 4:18), my
    code works fine for the first (feature) test, and the factory
    function works fine in tinker.
  • I have tried all kinds of different filepaths for 'App\Project', and
    also tried static Project::class type references.
  • My phpunit didn't run tests unless I prefixed the word 'test', even
    when filtering to the exact test name, so I believe this may be due
    to an underlying phpunit version difference.

My unit test:

namespace Tests\Unit;

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

class ProjectTest extends TestCase
{

    use RefreshDatabase;

    public function test_it_has_a_path()
    {
        $project = factory('App\Project')->create();
        $this->assertEquals('/project/' . $project->id, $this->path());
    }
}

My Project factory

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

use App\Project;
use Faker\Generator as Faker;

$factory->define(Project::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'description' => $faker->sentence
    ];
});

My show method

public function show(Project $project)
    {
        return view('projects.show', compact('project'));
    }

My route

Route::get('projects/{project}', 'ProjectsController@show');

and the working feature test (for reference)

    public function test_a_user_can_view_a_project()
    {
        $this->withoutExceptionHandling();
        $project = factory('App\Project')->create();

        $this->get("/projects/" . $project->id)
            ->assertSee($project->title)
            ->assertSee($project->description);
    }

答案1

得分: 4

我在Laracasts论坛上找到了解决我的问题的答案:

原因是因为单元测试现在扩展自PHPUnit测试用例类,而不是框架测试用例类。

因此,在单元测试中应避免使用工厂。这是最近的一个更改。

为了仍然能够使用工厂,您应该导入此测试用例:

use Tests\TestCase;

并移除这个:

use PHPUnit\Framework\TestCase;

这是更改的链接:

https://github.com/laravel/framework/commit/e30a0c979d98f2f1f7b6c565e4002734237a280b

英文:

I got this answer on the Laracasts forum that solved my problem:
the reason is because the unit test now extends from the PHPUnit testcase class instead of the framework testcase..

So you should avoid using factory in Unit tests. This was a change recently..

To be able to still use the factory, you should import this TestCase.

use Tests\TestCase;

And remove this:

use PHPUnit\Framework\TestCase;

And here is the change:

https://github.com/laravel/framework/commit/e30a0c979d98f2f1f7b6c565e4002734237a280b

huangapple
  • 本文由 发表于 2020年1月3日 22:46:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/59580569.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定