【问题标题】:How to define custom message on testing JSON in Laravel if assertation fails?如果断言失败,如何在 Laravel 中定义测试 JSON 的自定义消息?
【发布时间】:2021-12-15 02:20:04
【问题描述】:

我的 Laravel 项目中有这个测试:

// here are some test function configurations

// found nothing if not match
$this->post(action([TagController::class, 'search'], '!! Not foundable name !!'))
    ->assertOk()
    ->assertJsonCount(0, 'data');

// found it if match
$this->post(action([TagController::class, 'search'], $matchName))
    ->assertOk()
    ->assertJsonCount(1, 'data');

// found it if partly match
$this->post(action([TagController::class, 'search'], $partlyMatchName))
    ->assertOk()
    ->assertJsonCount(1, 'data');

现在如果测试失败,我会看到这个结果:

Failed to assert that the response count matched the expected 0
Failed asserting that actual size 4 matches expected size 0.

这对我来说并不过分,我不知道哪个断言失败以及确切原因。我想为这种情况定义自定义消息。

我想做这样的事情:

->assertJsonCount(
    0,
    'data',
    'It should found noting, because of conditions are not match'
);

在这种情况下,有没有办法向测试用户发送自定义消息?

【问题讨论】:

    标签: laravel laravel-testing


    【解决方案1】:

    您应该覆盖Illuminate\Testing\TestReponse 类的decodeResponseJson() 方法。

    在Tests命名空间中创建TestResponse和AssertableJsonString两个类,如下:

    测试响应

    namespace Tests;
    
    use Illuminate\Testing\Assert as PHPUnit;
    
    class TestResponse extends \Illuminate\Testing\TestResponse
    {
        /**
         * @inheritDoc
         */
        public function decodeResponseJson()
        {
            $testJson = new AssertableJsonString($this->getContent());
    
            $decodedResponse = $testJson->json();
    
            if (is_null($decodedResponse) || $decodedResponse === false) {
                if ($this->exception) {
                    throw $this->exception;
                } else {
                    PHPUnit::fail('Invalid JSON was returned from the route.');
                }
            }
    
            return $testJson;
        }
    }
    

    AssertableJsonString

    namespace Tests;
    
    use Illuminate\Testing\Assert as PHPUnit;
    
    class AssertableJsonString extends \Illuminate\Testing\AssertableJsonString implements \ArrayAccess, \Countable
    {
        /**
         * @inheritDoc
         */
        public function assertCount(int $count, $key = null, $message="Failed to assert that the response count matched the expected %d")
        {
            if (! is_null($key)) {
                PHPUnit::assertCount(
                    $count, data_get($this->decoded, $key),
                    sprintf($message, $count)
                );
    
                return $this;
            }
    
            PHPUnit::assertCount($count,
                $this->decoded,
                sprintf($message, $count)
            );
    
            return $this;
        }
    }
    

    现在,您需要在AppServiceProvider 的boot 方法中将 Laravel TestResponse 类绑定到您的自定义 TestResponse,如下所示:

    public function boot()
    {
        $this->app->bind(\Illuminate\Testing\TestResponse::class,\Tests\TestResponse::class);
    }
    

    注意:您需要将%d 放入您的消息格式中,以替换为sprintf() 函数。

    【讨论】:

    • 听起来不错,但我正在寻找 Laravel 或 PHPUnit 的内置方式。
    • 由于消息是硬编码的,我认为目前没有办法以 laravel 的方式实现这一点。
    猜你喜欢
    • 2023-03-10
    • 2021-05-19
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    相关资源
    最近更新 更多