Как определить пользовательское сообщение при тестировании JSON в Laravel в случае сбоя утверждения?

#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.