没有连接到数据库的Laravel模型工厂

13

我想在一些PHPUnit测试中使用Laravel的模型工厂。我唯一想做的事情就是创建一个模型实例而不将其保存到数据库中。

为什么模型工厂需要连接到数据库?这些测试必须在没有配置数据库的CI环境中通过。

当我使用new App\Model($dataArray)手动创建模型时,测试会通过且不需要连接。

我在其他地方使用了模型工厂,所以我想在这些测试中重用它,以避免代码重复。

我正在使用MongoDB和jenssegers/laravel-mongodb库,但我猜想这并不重要——在纯Eloquent和例如MySQL数据库中,问题也将是相同的。

可在没有数据库的情况下正常工作的测试:

class ModelTransformerTest extends TestCase
{
    public function testTransformMinimalModelData()
    {
        $data = [
            '_id' => $faker->md5,
            'email' => $faker->email,
        ];

        $model = new App\Model($data);
        // […];
    }
}

我的模型工厂

$factory->defineAs(Model::class, 'base', function ($faker) {
    return [
        '_id' => $faker->md5,
        'email' => $faker->email,
    ];
});

需要数据库连接的测试:

class ModelTransformerTest extends TestCase
{
    public function testTransformMinimalModelData()
    {
        $model = factory(App\Model::class, 'base')->make();
        // […];
    }
}

完整的堆栈跟踪信息:

Error: Class 'MongoDB\Driver\Manager' not found

app\vendor\mongodb\mongodb\src\Client.php:56
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\Connection.php:147
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\Connection.php:37
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\MongodbServiceProvider.php:27
app\vendor\illuminate\database\DatabaseManager.php:173
app\vendor\illuminate\database\DatabaseManager.php:68
app\vendor\illuminate\database\Eloquent\Model.php:3282
app\vendor\illuminate\database\Eloquent\Model.php:3248
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\Eloquent\Model.php:523
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\Eloquent\Model.php:284
app\vendor\illuminate\database\Eloquent\Model.php:443
app\vendor\illuminate\database\Eloquent\Model.php:281
app\vendor\illuminate\database\Eloquent\FactoryBuilder.php:142
app\vendor\illuminate\database\Eloquent\Model.php:2286
app\vendor\illuminate\database\Eloquent\FactoryBuilder.php:143
app\vendor\illuminate\database\Eloquent\FactoryBuilder.php:106
app\tests\phpunit\Transformers\ModelTransformerTest.php:25
\php\pear\PHPUnit\TextUI\Command.php:176
\php\pear\PHPUnit\TextUI\Command.php:129

你可以使用SQLite来实现这个功能。Laravel提供了一个选项,可以在内存中创建SQLite数据库。因此,你在技术上拥有一个数据库,但它不会填充你的MongoDB或MySQL等其他数据库。一旦测试完成,该数据库将从内存中删除。 - user3425867
3个回答

1
我认为目前这是不可能的。 make() 方法调用 newModelInstance(),后者试图设置数据库连接。
您可以自行查看源代码

1

您是否尝试使用DatabaseTransactions

例如:

use Illuminate\Foundation\Testing\DatabaseTransactions;
class ModelTransformerTest extends TestCase
{
    use DatabaseTransactions;
}

0
我通常会创建一个类似的测试数据库,并在该数据库上运行所有的测试。
这样可以确保你的测试数据库类型与生产环境相同,而且你不会触碰生产数据库来运行测试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接