Laravel 8-使用“ Date Mutators”和Faker的PHPUnit测试问题

问题描述

我注意到在模型中将protected dates数组中的Date Mutator字段设置为Model,将Faker中使用的日期格式修改Carbon对象,并且不返回在其中设置的格式Faker;这正常吗?

为解释问题,模型类似于:

<?PHP

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Post extends Model
{
    use HasFactory;

    protected $dates = [
        'seen_at'
    ];

    // other code here...
}

Factory类包含:

<?PHP
namespace App\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
use App\Models\Post;

class PostFactory extends Factory
{
    protected $model = Post::class;
    public function deFinition()
    {
        return [
            'number'         => $this->faker->randomDigit,'seen_at'        => $this->faker->date($format = 'Y-m-d\TH:i:s.vP',$max = 'Now'),'quality'        => $this->faker->unique()->regexify('[A-D][A-D]'),];
    }
}

Test类是:

<?PHP
namespace App\Tests\Feature;

use Tests\TestCase;
use App\Factories\PostFactory;

class PostControllerTest extends TestCase
{
    public function setUp(): void
    {
        parent::setUp();

        $post = PostFactory::new()->make();
        dd($post->seen_at);

        // other code here....
    }
}

运行测试,dd()返回:

Illuminate\Support\Carbon @228109214 {#2283
  #constructedobjectId: "00000000486a8e5f00000000514b58c9"
  #localMonthsOverflow: null
  #localYearsOverflow: null
  #localStrictModeEnabled: null
  #localHumanDiffOptions: null
  #localToStringFormat: null
  #localSerializer: null
  #localMacros: null
  #localGenericMacros: null
  #localFormatFunction: null
  #localTranslator: null
  #dumpProperties: array:3 [
    0 => "date"
    1 => "timezone_type"
    2 => "timezone"
  ]
  #dumpLocale: null
  date: 1977-03-25 03:40:14.0 +00:00
}

dateFaker中指定的格式不匹配,应该为'Y-m-d\TH:i:s.vP';但是是1977-03-25 03:40:14.0 +00:00

如果我从seen_at数组中删除protected $dates,再次运行测试,输出将正确:

"1970-02-10T03:13:34.000+00:00"

另一种想法是,如果我dd()Faker生成protected $dates包含seen_at的整个模型:

class PostControllerTest extends TestCase
{
    public function setUp(): void
    {
        parent::setUp();

        $post = PostFactory::new()->make();
        dd($post);

        // other code here....
    }
}

包含正确日期的输出

App\Models\Post {#2399
  #table: "post"
  . . .
  #attributes: array:39 [
    "number" => 8
    "seen_at" => "1970-02-10T03:13:34.000+00:00"
    "quality" => "AB"
  ]
  . . .
  #guarded: array:1 [
    0 => "*"
  ]
}

这种行为正常吗?如果为“是”,如何返回正确的日期格式?

谢谢。

解决方法

我和我的同事遇到了同样的问题。我们是这样解决的:

   class PostTest extends TestCase
   {
    public function test_can_create_post() {
        $data = [
            ...//data
            'seen_at' => $this->faker->date(),];

        $post = null;

        try {
            $post = Post::create($data);
        } catch (QueryException $e) {
            throw $e;
        }
        
        $this->assertInstanceOf(Post::class,$post);
        ...
        $this->assertEquals($data['seen_at'].' 00:00:00',$post->seen_at);
    }
}

我的 TestCase 类如下所示:

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Foundation\Testing\WithFaker;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication,WithFaker;
}

通过这个配置,测试成功!!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...