#laravel #laravel-testing
Вопрос:
У меня есть этот тест в моем проекте Laravel:
// here are some test function configurations // found nothing if not match $this-gt;post(action([TagController::class, 'search'], '!! Not foundable name !!')) -gt;assertOk() -gt;assertJsonCount(0, 'data'); // found it if match $this-gt;post(action([TagController::class, 'search'], $matchName)) -gt;assertOk() -gt;assertJsonCount(1, 'data'); // found it if partly match $this-gt;post(action([TagController::class, 'search'], $partlyMatchName)) -gt;assertOk() -gt;assertJsonCount(1, 'data');
Теперь я вижу этот результат, если тест не удался:
Failed to assert that the response count matched the expected 0 Failed asserting that actual size 4 matches expected size 0.
Для меня это не слишком мудрено, я не вижу, какое утверждение потерпело неудачу и почему именно. Я хочу определить пользовательское сообщение для этого случая.
Я хочу сделать что-то вроде этого:
-gt;assertJsonCount( 0, 'data', 'It should found noting, because of conditions are not match' );
Есть ли какой-либо способ отправить пользовательское сообщение пользователю тестера в этом случае?
Ответ №1:
Вы должны переопределить decodeResponseJson()
метод IlluminateTestingTestReponse
класса.
Создайте два класса TestResponse
и AssertableJsonString
в Tests
пространстве имен следующим образом:
Тестовый ответ
namespace Tests; use IlluminateTestingAssert as PHPUnit; class TestResponse extends IlluminateTestingTestResponse { /** * @inheritDoc */ public function decodeResponseJson() { $testJson = new AssertableJsonString($this-gt;getContent()); $decodedResponse = $testJson-gt;json(); if (is_null($decodedResponse) || $decodedResponse === false) { if ($this-gt;exception) { throw $this-gt;exception; } else { PHPUnit::fail('Invalid JSON was returned from the route.'); } } return $testJson; } }
Строка assertablejson
namespace Tests; use IlluminateTestingAssert as PHPUnit; class AssertableJsonString extends IlluminateTestingAssertableJsonString 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-gt;decoded, $key), sprintf($message, $count) ); return $this; } PHPUnit::assertCount($count, $this-gt;decoded, sprintf($message, $count) ); return $this; } }
Теперь вам нужно привязать класс Laravel TestResponse к вашему пользовательскому TestResponse следующим boot
образом AppServiceProvider
:
public function boot() { $this-gt;app-gt;bind(IlluminateTestingTestResponse::class,TestsTestResponse::class); }
Обратите внимание: вам необходимо разместить %d
в своем формате сообщение, которое будет заменено sprintf()
функцией.
Комментарии:
1. Звучит неплохо, но я ищу встроенный способ Laravel или PHPUnit.
2. Поскольку сообщение жестко закодировано, я не думаю, что на данный момент существует способ добиться этого с помощью laravel.