首页 > 解决方案 > 为什么在 PHPUnit 测试中调用 Collection 的 toArray() 方法不会将嵌套对象转换为数组?

问题描述

预期行为:

集合 toArray()方法应该将集合转换为普通集合array,并将集合的所有嵌套对象Arrayable作为数组的实例。

实际行为:

toArray()方法将集合转换为普通array对象,但不会转换嵌套对象。请注意,仅当toArray()通过 PHPUnit 调用时才会观察到此行为。当toArray()在应用程序内或通过 Laravel Tinker 调用函数时,它会按预期工作。

重现步骤:

测试失败的存储库

克隆、安装包、运行 PHPUnit。

<?php

namespace Tests\Unit;

use App\User;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class CollectionToArrayTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function it_converts_nested_objects_that_are_an_instance_of_arrayable_to_an_array()
    {
        factory(User::class)->create();

        $users = User::get();

        // passed
        $this->assertInstanceOf(Arrayable::class, $users[0]);

        // Failed asserting that App\User Object is of type "array"
        $this->assertIsArray($users->toArray()[0]);

        // passed
        $this->assertIsArray($users->toArray()[0]->toArray());
    }
}

观察:

  1. 它以前工作过,可能与以前版本的 PHP 和 PHPUnit 一起工作,但是我无法确定它停止的那一刻。

  2. 似乎在提供的 PHPUnit 测试中对 Collection调用时未调用EnumeratesValues::toArray() 。->toArray()

Laravel 版本:7.0.7
PHP 版本:7.3.15
PHPUnit 版本:8.5.2

标签: phplaraveleloquentphpunitlaravel-valet

解决方案


解决了这个问题。

我在全球范围内安装了 Laravel Valet 和 PHPUnit。Valet 需要tightenco/collect与 Laravel Collections 冲突的包。

运行 PHPUnit 时,\Illuminate\Support\Collection被替换为Tightenco\Collect\Support\Collection不同的工作方式。

因此,我删除了全局 PHPUnit 并改用本地版本。

我创建了一个GitHub 问题


推荐阅读