Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Laravel 6中进行单元测试时处理模型关系状态/状态的最佳方法?_Laravel_Unit Testing_Laravel 6 - Fatal编程技术网

在Laravel 6中进行单元测试时处理模型关系状态/状态的最佳方法?

在Laravel 6中进行单元测试时处理模型关系状态/状态的最佳方法?,laravel,unit-testing,laravel-6,Laravel,Unit Testing,Laravel 6,我在Laravel 6.x中使用SQLite进行了以下单元测试: <?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Entry; use App\EntryStatus; use Faker\Generator as Faker; $factory->define(Entry::class, function (Faker $faker) { return [

我在Laravel 6.x中使用SQLite进行了以下单元测试:

<?php

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

use App\Entry;
use App\EntryStatus;
use Faker\Generator as Faker;

$factory->define(Entry::class, function (Faker $faker) {
    return [
        'user_id' => 1,
        'caption' => $faker->sentence(10),
        'entry_status_id' => EntryStatus::where('name', 'pending')->first()->id,
    ];
});

$factory->state(Entry::class, 'awaiting_payment', [
    'entry_status' => EntryStatus::where('name', 'awaiting_payment')->first()->id,
]);
关于如何修复这个错误,我有一些想法,但我想知道在单元测试和“Laravel方式”方面,这里的最佳实践是什么

按照我的想法,我有一个EntryStatus表,它的静态状态为'pending'=>0,'Waiting_payment'=>1,'payment'=>2等。我在我的App\Entry model>App\EntryStatus中创建了一个关系。想法如下:

  • 原计划;对于单元测试,每次测试我都需要为静态EntryStatus表种子。查看文档,我会使用类似setUp()>$this->artisan('db:seed')的东西。但这感觉会让测试变得很慢。除非有办法在所有测试开始之前对数据库进行一次种子设定

  • 尝试创建一个创建静态数据的工厂('pending'=>0,'Waiting_payment'=>1),但每次我都需要手动更新数据库种子和工厂,以匹配看似笨拙的数据

  • 在Laravel文档测试文档中,他们有这个例子$工厂->状态(应用程序\用户::类,'拖欠',['account\u status'=>'拖欠',])。这使我认为我可以完全删除关系表EntryStatus,并在条目中使用字符串列来表示状态。我认为这是最好的解决方案,但我担心我们使用ID作为状态是有原因的,因为我认为它们在搜索查询中更快。但如果没有,我的雕像将被修复,这似乎是最有说服力的解决方案


  • 另一种选择是将状态存储为整数,并记下状态是什么整数,但这似乎不正确。

    记录尚未创建,在工厂中以这种方式分配静态关系不是一个好主意

    您可以使用工厂
    创建
    ,然后在测试用例中分配关系

    例如:

    条目
    工厂

    $factory->define(Entry::class, function (Faker $faker) {
        return [
            'user_id' => factory(User)->create()->id,
            'caption' => $faker->sentence(10),
            'entry_status_id' => factory(EntryStatus)->create()->id,
        ];
    });
    
    $factory->define(EntryStatus::class, function (Faker $faker) {
        return [
            'name' => $faker->word,
            'entry_status' => $faker->numberBetween(0, 2) //Its better start from 1 though
        ];
    });
    
    $factory->define(User::class, function (Faker $faker) {
        return [
            'name' => $faker->word
        ];
    });
    
    EntryStatus
    factory

    $factory->define(Entry::class, function (Faker $faker) {
        return [
            'user_id' => factory(User)->create()->id,
            'caption' => $faker->sentence(10),
            'entry_status_id' => factory(EntryStatus)->create()->id,
        ];
    });
    
    $factory->define(EntryStatus::class, function (Faker $faker) {
        return [
            'name' => $faker->word,
            'entry_status' => $faker->numberBetween(0, 2) //Its better start from 1 though
        ];
    });
    
    $factory->define(User::class, function (Faker $faker) {
        return [
            'name' => $faker->word
        ];
    });
    
    用户
    工厂

    $factory->define(Entry::class, function (Faker $faker) {
        return [
            'user_id' => factory(User)->create()->id,
            'caption' => $faker->sentence(10),
            'entry_status_id' => factory(EntryStatus)->create()->id,
        ];
    });
    
    $factory->define(EntryStatus::class, function (Faker $faker) {
        return [
            'name' => $faker->word,
            'entry_status' => $faker->numberBetween(0, 2) //Its better start from 1 though
        ];
    });
    
    $factory->define(User::class, function (Faker $faker) {
        return [
            'name' => $faker->word
        ];
    });
    
    在您的测试用例中,开始将事物链接在一起(如果需要)

    您可以在创建状态后检查

    $factory
        ->state(EntryStatus::class, 'awaiting_payment', ['name' => 'awaiting_payment'])
        ->afterCreatingState(EntryStatus::class, 'awaiting_payment', function ($entryStatus, $faker) {
            factory(Entry::class)->create([
                'entry_status_id' => $entryStatus->id,
            ]);
        });
    

    根据错误,您显然没有名称为“等待付款”的输入状态。只是种下种子不是很有帮助吗?或者我遗漏了一点?也许就这么简单,你会建议我如何使用SQLite进行单元测试?在不降低测试速度的情况下?我想您已经在每次执行时迁移数据库了?我有一个大项目,所有奇怪的诡计都在进行,sqlite的速度非常快:)似乎是编写可维护代码的最佳方式。