Бесполезное сообщение об ошибке при использовании BackedEnum и assertJson
Возможно, вам интересно, почему...
Вот интересный сценарий, с которым недавно столкнулся.
Допустим, необходимо протестировать ответ API, и его значение включает `BackedEnum
`:
// app/Enums/Urgency.php enum Urgency: string { case LOW = 'low'; case MEDIUM = 'medium'; case HIGH = 'high'; } // tests/Feature/ExampleTest.php $response->assertJson([ 'data' => [ 'urgency' => Urgency::LOW, ], ])
Этот тест завершится неудачей, потому что перечисление не соответствует строковому значению в JSON-ответе. Это легко исправить, просто добавьте `->value
` к перечислению, и тест будет пройден. Ничего страшного!
Но вот тут-то и становится интересно. Посмотрите внимательно на сообщение об ошибке при неудачном завершении теста:
Unable to find JSON: [{ "data": { "urgency": "low" } }] within response JSON: [{ "data": { "urgency": "low" } }]
Оба значения совпадают! Этот пример предельно прост, поэтому странности легче заметить, но теперь представьте это в ответе с десятками ключей и значений.
Внутри метода теста Laravel `assertJson
` он откладывает утверждение для `PHPUnit::assertArraySubset
`. Как и ожидалось, метод PHPUnit воспринимает объект `BackedEnum` и строковое значение как разные, поэтому тест проваливается, как и должно быть.
Но когда Laravel вызывает это утверждение PHPUnit, он также передает сообщение об ошибке, чтобы показать, если утверждение завершилось неудачно. И чтобы сделать сообщение об ошибке более красиво оформленным, он форматирует ожидаемые и фактические значения с помощью `json_encode
` с красивым выводом.
Когда вы `json_encode
` объект `BackedEnum
`, он вернет строковое значение перечисления, а не сам объект перечисления.
Таким образом, тест проваливается, но сообщение об ошибке выглядит так, как будто он должен быть пройден.