简体   繁体   中英

Laravel Unit Testing Inconsistency

Hi I am following the laravel course from laracast , but faced some difficulty following the course.

In the app, there is a Post Model with a static function that returns grouped records:

Post.php

public static function archives()
{

    return static::selectRaw('year(created_at) as year, monthname(created_at) month, count(*) published')
    ->groupBy('year', 'month')
    ->orderByRaw('min(created_at) desc')
    ->get()
    ->toArray();
}

On the other hand, a test case aims to test the Post::archives() function:

ExampleTest.php

public function testBasicTest()
{

    // GIVEN I have two records in the database that are posts,
    // and each one is posted a month apart.
    $first = factory(Post::class)->create();

    $second = factory(Post::class)->create([
       'created_at' => \Carbon\Carbon::now()->subMonth()
    ]);
    // WHEN I fetch the archives
    $posts = \App\Post::archives();
    // dd($posts);
    // THEN the response should be in the proper format
    $this->assertEquals([
        [
            "year" => $first->created_at->format('Y'),
            "month" => $first->created_at->format('F'),
            "published" => 1
        ],
        [
            "year" => $first->created_at->format('Y'),
            "month" => $first->created_at->format('F'),
            "published" => 1
        ],
    ], $posts);
}

However, the assertion failed, because $posts is an array of object instead of an array of array, even though Post::archives() specifically converted the results with toArray() .

Dumping it on tinker:

$posts = \App\Post::archives()
[
 [
   "year" => 2014,
   "month" => "March",
   "published" => 2,
 ],
 [
   "year" => 2014,
   "month" => "February",
   "published" => 1,
 ],
 [
   "year" => 2013,
   "month" => "February",
   "published" => 1,
 ],
]

The error on phpunit

1) Tests\Unit\ExampleTest::testBasicTest
Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
 Array (
-    0 => Array (...)
-    1 => Array (...)
+    0 => App\Post Object (...)
+    1 => App\Post Object (...)
 )

dd($posts) derives:-

    ..array:2 [
  0 => App\Post {#863
    #guarded: []
    #connection: "mysql"
    #table: null
    #primaryKey: "id"
    #keyType: "int"
    +incrementing: true
    #with: []
    #withCount: []
    #perPage: 15
    +exists: true
    +wasRecentlyCreated: false
    #attributes: array:3 [
      "year" => 2018
      "month" => "April"
      "published" => 1
    ]
    #original: array:3 [
      "year" => 2018
      "month" => "April"
      "published" => 1
    ]
    #changes: []
    #casts: []
    #dates: []
    #dateFormat: null
    #appends: []
    #dispatchesEvents: []
    #observables: []
    #relations: []
    #touches: []
    +timestamps: true
    #hidden: []
    #visible: []
    #fillable: []
  }
  1 => App\Post {#864
    #guarded: []
    #connection: "mysql"
    #table: null
    #primaryKey: "id"
    #keyType: "int"
    +incrementing: true
    #with: []
    #withCount: []
    #perPage: 15
    +exists: true
    +wasRecentlyCreated: false
    #attributes: array:3 [
      "year" => 2018
      "month" => "March"
      "published" => 1
    ]
    #original: array:3 [
      "year" => 2018
      "month" => "March"
      "published" => 1
    ]
    #changes: []
    #casts: []
    #dates: []
    #dateFormat: null
    #appends: []
    #dispatchesEvents: []
    #observables: []
    #relations: []
    #touches: []
    +timestamps: true
    #hidden: []
    #visible: []
    #fillable: []
  }
]

Why is it behaving as such in the TestCase?

While it might be extra labor, and I can't exactly tell you why it happens, you might want to explicitly call the attributes in an outside array, as in:

$postsArray = [
    "year" => $posts->year,
    "month" => $posts->month,
    "published" => $posts->published
];

I think the reason it is doing that is because it first creates the model object and then attempts to access the query search, and for whatever reason it simply returns the object instance. I would need to read a little more before giving a good conclusion. I was going to say that it might just be failing to find anything with the query and thus returning the object itself, but I haven't actually ever used a model search that way so I can't say with precision that's what happens.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM