doumo0206 2017-02-16 21:52
浏览 93

在Laravel中进行HTTP测试时查看JSON差异

I am running some HTTP tests in Laravel 5.4, mainly using the assertJson helper method with phpunit. When I run other tests on my models using assertEquals I usually get very good feedback about specifically which properties, fields, etc. are different than expected. However, the assertJson method only tells me that there are differences, but not what those differences are. For instance, let's say I have a route my/route that returns this JSON:

{
  "name": "test",
  "foo": "bar"
}

I might run this Laravel test:

$response = $this->get("my/route");

$response->assertJson([
    'name' => 'test',
    'foo' => 'baz',
]);

My test fails as expected. However, the resulting message is pretty unhelpful:

Failed asserting that an array has the subset Array &0 (
    'name' => 'test'
    'foo' => 'baz'
).

For a non-trivial example with larger response, it can get pretty annoying to try to figure out what is different between the JSON responses. Is there any way to view the specific differences between the expected and actual outputs, instead of just knowing that something is different between the two?

  • 写回答

1条回答 默认 最新

  • dpp42324 2017-02-17 08:12
    关注

    You could wrap your assertion in a try-catch and then if the assertion fails you'll be able to create a new message and throw a new exception.

    /**
     * @test
     * @group new
     */
    public function testExample()
    {
        $response = $this->get('test');
    
        try {
            $expected = [
                'name' => 'test',
                'foo'  => 'barz',
            ];
    
            $response->assertJson($expected);
        } catch (\Exception $e) {
    
            $exporter = new \SebastianBergmann\Exporter\Exporter();
    
            $message = 'The following items we\'re expected to be different ' .
                $exporter->export($this->arrayRecursiveDiff($expected, $response->decodeResponseJson()));
    
            throw new \PHPUnit_Framework_ExpectationFailedException($message);
        }
    }
    
    public function arrayRecursiveDiff($array1, $array2)
    {
        $return = [];
    
        foreach ($array1 as $key => $value) {
            if (is_array($array2) && array_key_exists($key, $array2)) {
                if (is_array($value)) {
                    $recursiveDiff = $this->arrayRecursiveDiff($value, $array2[$key]);
                    if (count($recursiveDiff)) {
                        $return[$key] = $recursiveDiff;
                    }
                } else {
                    if ($value != $array2[$key]) {
                        $return[$key] = $value;
                    }
                }
            } else {
                $return[$key] = $value;
            }
        }
    
        return $return;
    }
    

    Please note the arrayRecursiveDiff method isn't fully tested, however, there are quite a few different examples floating around for how to compare multidimensional arrays.

    Hope this helps!

    评论

报告相同问题?

悬赏问题

  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)