代码之家  ›  专栏  ›  技术社区  ›  D.R.

Laravel系列。有什么资产结构方法吗?

  •  4
  • D.R.  · 技术社区  · 8 年前

    我正在编写测试,我想断言,返回的集合有一些特定的结构。

    用于断言 json 我正在使用 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'],
    ]);
    

    我会接受的

    这也是一个答案,但如果是一个如何验证此类嵌套集合的示例。

    3 回复  |  直到 7 年前
        1
  •  3
  •   Oluwatobi Samuel Omisakin    8 年前

    集合实例上没有此类函数,您可以执行的最接近的操作是:

    • 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() 拥有 assertArrayStructure() 这个工作测试:

    /**
     * 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;
    }
    
        2
  •  3
  •   Asur    8 年前

    答案是 ,您只需在 API documentation ,命名空间中没有方法 Illuminate\Support\Collection 这就是你想要的。(您可以找到Laravel断言方法 here )

    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 here .
    • 正如方法comment指定的那样,它返回一个 Illuminate\Foundation\Testing\TestResponse .
    • 寻找构造函数 at the docs 看看它需要什么,一个通用的响应对象, Illuminate/Http/Response .

    希望这对你有帮助。

        3
  •  0
  •   shaedrich Gabin traverse    4 年前

    截至拉腊维尔8。x、 其他答案有些过时。您可以使用 AssertableJsonString TestResponse 在引擎盖下使用:

    (new \Illuminate\Testing\AssertableJsonString($yourJson))->assertStructure($yourStructure);
    
    推荐文章