我想在一些PHPUnit测试中使用Laravel的模型工厂。我唯一想做的就是创建一个Model实例,而不将其保存到数据库中。
为什么模型工厂需要连接到数据库?这些测试必须在没有配置数据库的CI环境中通过。
当我通过new App'Model($dataArray)
手动创建模型时,测试通过并且不需要连接。
我在其他地方使用模型工厂,所以我想在测试中重用它,以避免代码重复。
我正在使用MongoDB和jenssegers/laravel-mongodb库,但我猜它没有关系-在纯雄辩和例如MySQL数据库中,问题是相同的。
没有数据库的测试:
class ModelTransformerTest extends TestCase
{
public function testTransformMinimalModelData()
{
$data = [
'_id' => $faker->md5,
'email' => $faker->email,
];
$model = new App'Model($data);
// […];
}
}
My Model Factory
$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
我认为这目前是不可能的。make()
方法调用试图建立数据库连接的newModelInstance()
。
您可以自己查看源代码
您是否尝试使用DatabaseTransactions?
例如use Illuminate'Foundation'Testing'DatabaseTransactions;
class ModelTransformerTest extends TestCase
{
use DatabaseTransactions;
}
我通常会创建一个类似的测试数据库,并在该数据库上运行所有测试。
它确保您的测试DB类型与生产数据库相同,并且您不会在运行测试时触及生产数据库。