工厂帮助程序在 PHPUnit 设置方法中不起作用

Factory helper not working within PHPUnit setup method

提问人:miken32 提问时间:11/9/2018 更新时间:11/9/2018 访问量:1618

问:

编写一些单元测试,我想在类中的测试完成之前创建一个对象。所以我设置了方法:setUpBeforeClass()

<?php
namespace Tests\Unit;
use Tests\TestCase;
use App\Location;
class UserTests extends TestCase {
    const FAKEID = 9999999;
    public static function setUpBeforeClass() : void {
        parent::setUpBeforeClass();
        factory(Location::class)->make(["id" => self::FAKEID])->save();
    }
}

但是当我尝试运行它时,我收到以下错误:

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

但是工厂类设置正确。事实上,如果我将同一行向下移动到我的一个测试函数,它就可以完美地工作。

public function testCreateUser() {
    factory(Location::class)->make(["id" => self::FAKEID])->save();
    // do other stuff...
}

唯一让我印象深刻的是它是一种静态方法,但我不知道为什么这会阻止工厂类工作。setUpBeforeClass()

php laravel phpunit

评论


答:

3赞 Sven van Zoelen 11/9/2018 #1

Laravel在类中的方法中做了很多设置。该方法在此之前被调用,这就是为什么您的工厂尚未加载的原因。setUp()TestCasesetUpBeforeClass()

Laravel 的类方法(见类):TestCasesetup

/**
 * Setup the test environment.
 *
 * @return void
 */
protected function setUp()
{
    if (! $this->app) {
        $this->refreshApplication();
    }

    $this->setUpTraits();

    foreach ($this->afterApplicationCreatedCallbacks as $callback) {
        call_user_func($callback);
    }

    Facade::clearResolvedInstances();
    Model::setEventDispatcher($this->app['events']);

    $this->setUpHasRun = true;
}

更改代码以改用:setUp

protected static function setUp() : void 
{
    parent::setUp();

    factory( Location::class )->make( ["id" => self::FAKEID] )->save();
}

评论

0赞 miken32 11/9/2018
但是此方法在每次测试之前运行。在每次测试之前都必须创建和插入新记录,并在每次测试后将其删除,这似乎是一种浪费。
0赞 Sven van Zoelen 11/9/2018
我明白你在说什么,但这就是你嫁给一个框架时得到的。Laravel在每次测试前都已经这样做了。你想使用基于 Laravel 的工厂,所以当它被设置和运行时,你需要 Laravel,那是在调用 TestCase 夹具之后。setUp
0赞 Sven van Zoelen 11/9/2018
顺便说一句,您始终应该在每次测试开始时重置状态。在单元测试中,基于以前的测试状态进行测试是禁忌。这就是为什么 Laravel 也会在每次测试中重置自己。
0赞 miken32 11/9/2018
好吧,我正在做的只是在我实际测试的记录上插入一些外键所需的记录。就像我使用的示例一样,我需要先设置一个位置,然后才能创建用户。我希望我会接受这个答案,只是似乎是不必要的数据库访问,经过数十次测试。
0赞 jminkler 8/24/2019
为什么这在 dataProvider 中也不起作用?有办法解决这个问题吗?