4

我正在编写测试并且我想断言,返回的集合具有某种特定的结构。

为了断言jsons 我在对象上使用assertJsonStructure()方法。Responce

我还没有找到类似的\Illuminate\Support\Collection. 我是否错过了一些包/框架方法。

我想要什么的一个例子

$collection = collect([
    'name'      => 'John',
    'surname'   => 'Smith',
    'birthoday' => [
        'day'   => 23,
        'month' => 5,
        'year'  => 1970,
    ],
]);

$collection->assertStructure([          //true
    'name',
    'surname',
    'birthday' => ['day', 'month', 'year'],
]);

我会接受

作为一个答案,但如果它是一个如何验证这样一个嵌套集合的例子。

4

2 回答 2

3

答案是否定的,您可以简单地在API 文档中查找自信的 laravel 方法,命名空间中没有方法可以满足Illuminate\Support\Collection您的需求。(你可以在这里找到 Laravel 自信的方法)

作为一个可行的替代方案,为什么你不只是序列化你的集合并用assertJsonStructure()方法检查它?

您可以使用response()帮助程序来填充Illuminate/Foundation/Testing/TestResponse

use Illuminate/Foundation/Testing/TestResponse;

$testResponse = new TestResponse(response()->json($collection->toArray());
return $testResponse->assertJsonStructure([
    'name',
    'surname',
    'birthday' => ['day', 'month', 'year'],
]);

我是如何得出这个解决方案的:

  • 您需要在测试中返回该方法的完全相同的对象,该对象$this->json()来自此处MakesHttpRequests的特征。
  • 正如方法注释所指定的,它返回一个Illuminate\Foundation\Testing\TestResponse.
  • 在文档中查找构造函数,看看它需要什么,一个通用响应对象,Illuminate/Http/Response.

希望这对您有所帮助。

于 2017-11-02T08:12:08.397 回答
3

Collection 实例上没有这样的功能,您可以做的最接近的是:

  • 检查它是否有一个钥匙has()
  • 检查它是否包含一些值contains()
  • 还有其他方法可以检查是否存在,但是

如果你需要灵感,可以通过 Laravel 实现的方式来assertJsonStructure()获得/Illuminate/Foundation/Testing/TestResponse.php

/**
 * Assert that the response has a given JSON structure.
 *
 * @param  array|null  $structure
 * @param  array|null  $responseData
 * @return $this
 */
public function assertJsonStructure(array $structure = null, $responseData = null)
{
    if (is_null($structure)) {
        return $this->assertJson($this->json());
    }

    if (is_null($responseData)) {
        $responseData = $this->decodeResponseJson();
    }

    foreach ($structure as $key => $value) {
        if (is_array($value) && $key === '*') {
            PHPUnit::assertInternalType('array', $responseData);

            foreach ($responseData as $responseDataItem) {
                $this->assertJsonStructure($structure['*'], $responseDataItem);
            }
        } elseif (is_array($value)) {
            PHPUnit::assertArrayHasKey($key, $responseData);

            $this->assertJsonStructure($structure[$key], $responseData[$key]);
        } else {
            PHPUnit::assertArrayHasKey($value, $responseData);
        }
    }

    return $this;
}

如您所见,如果存在子结构,则会进行递归调用来检查结构。

更新:

作为解决您问题的基本测试,我修改了assertJsonStructure()to haveassertArrayStructure()和这个工作测试:

/**
 * A basic test example.
 *
 * @return void
 */
public function testBasicTest()
{
    $collect = collect(['name' => '1', 'detail' => ['age' => 1,'class' => 'abc']]);

    $this->assertArrayStructure(['name', 'detail' => ['class', 'age']], $collect->toArray());
}


/**
 * Assert the array has a given structure.
 *
 * @param  array  $structure
 * @param  array  $arrayData
 * @return $this
 */
public function assertArrayStructure(array $structure, array $arrayData)
{
    foreach ($structure as $key => $value) {
        if (is_array($value) && $key === '*') {
            $this->assertInternalType('array', $arrayData);

            foreach ($arrayData as $arrayDataItem) {
                $this->assertArrayStructure($structure['*'], $arrayDataItem);
            }
        } elseif (is_array($value)) {
            $this->assertArrayHasKey($key, $arrayData);

            $this->assertArrayStructure($structure[$key], $arrayData[$key]);
        } else {
            $this->assertArrayHasKey($value, $arrayData);
        }
    }

    return $this;
}
于 2017-11-02T08:25:38.740 回答