【问题标题】:Timestamps are making my phpunit tests fail时间戳使我的 phpunit 测试失败
【发布时间】:2020-04-13 08:32:36
【问题描述】:

当我使用以下 PostResource 和 Post Test 时,我的测试成功了:

PostResource.php

public function toArray($request)
{
    return [
        'id' => $this->id,
        'title' => $this->title,
        'content' => $this->content,
        'slug' => $this->slug,
    ];
}

PostController.php

public function show(Post $post)
{
    return new PostResource($post);
}

ReadPostTest.php

/** @test */
public function a_user_can_read_a_single_post()
{
    $post = factory(Post::class)->create([
        'title' => 'A new post',
        'content' => "Some content",
        'slug' => "a-new-post",
    ]);

    //dd($post);

    $response = $this->json('GET', '/posts/' . $post->id)
            ->assertStatus(200)
            ->assertJsonFragment([ 'data' => [
                'title' => 'A new post',
                'content' => "Some content",
                'slug' => "a-new-post",
            ]]);

}

当我将 created_at 和 updated_at 添加到我的测试和资源中时,我遇到了失败。当我没有添加.000000Z 时,下面的测试显示。

phpunit

There was 1 failure:

1) Tests\Feature\ReadPostsTest::a_user_can_read_a_single_post
Unable to find JSON: 

[{
    "data": {
        "title": "A new post",
        "content": "Some content",
        "slug": "a-new-post",
        "created_at": "2018-12-06 21:13:26",
        "updated_at": "2018-12-06 21:13:26"
    }
}]

within response JSON:

[{
    "data": {
        "id": 1,
        "title": "A new post",
        "content": "Some content",
        "slug": "a-new-post",
        "created_at": "2018-12-06T21:13:26.000000Z",
        "updated_at": "2018-12-06T21:13:26.000000Z"
    }
}].


Failed asserting that an array has the subset Array &0 (
    'data' => Array &1 (
        'title' => 'A new post'
        'content' => 'Some content'
        'slug' => 'a-new-post'
        'created_at' => '2018-12-06 21:13:26'
        'updated_at' => '2018-12-06 21:13:26'
    )
).
--- Expected
+++ Actual
@@ @@
     'title' => 'A new post',
     'content' => 'Some content',
     'slug' => 'a-new-post',
-    'created_at' => '2018-12-06 21:13:26',
-    'updated_at' => '2018-12-06 21:13:26',
+    'created_at' => '2018-12-06T21:13:26.000000Z',
+    'updated_at' => '2018-12-06T21:13:26.000000Z',
   ),
 )

我尝试添加 000000Z 并遇到了同样的问题。

There was 1 failure:

1) Tests\Feature\ReadPostsTest::a_user_can_read_a_single_post
Unable to find JSON fragment: 

[{"data":{"content":"Some content","created_at":"2019-12-20 21:42:33.000000Z","id":1,"slug":"a-new-post","title":"A new post","updated_at":"2019-12-20 21:42:33.000000Z"}}]

within

[{"data":{"content":"Some content","created_at":"2019-12-20T21:42:33.000000Z","id":1,"slug":"a-new-post","title":"A new post","updated_at":"2019-12-20T21:42:33.000000Z"}}].
Failed asserting that false is true.

似乎我的 created_at 和 up_dated at 时间戳被搞砸了,我不知道为什么? 2019-12-20T21:42:33.000000Z这可能是我的测试失败的原因。我该如何解决这个问题?

【问题讨论】:

  • z 是区域标识符,也许你在某处添加z

标签: laravel phpunit laravel-6


【解决方案1】:

在你的后期模型工厂中使用碳,然后在 json 断言中使用 $post->created_at$post->updated_at

public function a_user_can_read_a_single_post()
{
    $post = factory(Post::class)->create([
        'title' => 'A new post',
        'content' => "Some content",
        'slug' => "a-new-post",
        "updated_at" => Carbon::now()->timestamp,
        "created_at" => Carbon::now()->timestamp
    ]);

    //dd($post);

    $response = $this->json('GET', '/posts/' . $post->id)
            ->assertStatus(200)
            ->assertJsonFragment([ 'data' => [
                'id' => 1,
                'title' => 'A new post',
                'content' => "Some content",
                'slug' => "a-new-post",
                "updated_at" => $post->updated_at,
                "created_at" => $post->created_at
            ]]);

}

由于某种原因,一串时间戳不起作用。希望其他人可以评论为什么。

【讨论】:

    【解决方案2】:

    您可能想使用 Carbon 的 setTestNow() 来修正测试期间“现在”的含义。

    假设您使用的是 Laravel。

    // Immutable, so you don't go insane.
    $now = \Carbon\CarbonImmutable::now()->micro(0);
    
    // Fix Carbon's 'now' to that time
    \Illuminate\Support\Carbon::setTestNow($now)
    // \Carbon\CarbonImmutable::setTestNow($now);
    
    // Your tests here
    // u = microseconds, but it's not set to '000000' in 'now', if you forget `->micro(0)`.
    // The 'Y-m-d\TH:i:s.u\Z' format works with Laravel 6.20.19 in march 2021, but YMMV.
    // ->assertJSon(['created_at' => $now->utc()->format('Y-m-d\TH:i:s.000000\Z'),])
    
    // Release Carbon's 'now' time to follow your clock again.
    \Illuminate\Support\Carbon::setTestNow($now)
    // \Carbon\CarbonImmutable::setTestNow($now);
    

    【讨论】:

      【解决方案3】:

      您似乎在为时间戳格式而苦苦挣扎。我遇到了同样的问题,并通过 Carbon 文档中的 JSON 序列化解决了它。在您的情况下,它必须如下所示:

      public function a_user_can_read_a_single_post()
      {
          $post = factory(Post::class)->create([
              'title' => 'A new post',
              'content' => "Some content",
              'slug' => "a-new-post",
              "updated_at" => Carbon::now()->timestamp,
              "created_at" => Carbon::now()->timestamp
          ]);
      
          $response = $this->json('GET', '/posts/' . $post->id)
                  ->assertStatus(200)
                  ->assertJsonFragment([ 'data' => [
                      'id' => 1,
                      'title' => 'A new post',
                      'content' => "Some content",
                      'slug' => "a-new-post",
                      "updated_at" => $post->updated_at->jsonSerialize(),
                      "created_at" => $post->created_at->jsonSerialize()
                  ]]);
      
      }
      

      可能有点晚了,但希望对其他人有所帮助。 祝你好运哥们。

      【讨论】:

        猜你喜欢
        • 2013-07-28
        • 1970-01-01
        • 2017-06-24
        • 2013-08-26
        • 1970-01-01
        • 2017-05-24
        • 2014-05-26
        • 2013-05-04
        • 2011-10-13
        相关资源
        最近更新 更多