Не все тестовые утверждения одинаково обрабатывают перечисления
Убедитесь, что знаете, как они работают
Вчера я поделился сценарием, в котором сбой теста с assertJson возвращал не очень полезную ошибку с перечислением.
Сегодня я хочу продолжить это обсуждение и обратить внимание на то, что не все тестовые утверждения одинаково обрабатывают перечисления.
Например, можно передать экземпляр BackedEnum непосредственно в assertExactJson, и он пройдет:
// app/Enums/Urgency.php
enum Urgency: string {
case LOW = 'low';
case MEDIUM = 'medium';
case HIGH = 'high';
}
// tests/Feature/ExampleTest.php
$response->assertExactJson([
'data' => [
'urgency' => Urgency::LOW, // здесь не требуется ->value
],
])Почему это проходит, в то время как аналогичный подход с assertJson проваливается?
Как уже говорилось ранее, assertJson передает данные в базовое утверждение PHPUnit.
Но в assertExactJson используется объект AssertableJsonString, позволяющий обработать данные перед передачей их в PHPUnit::assertEquals:
// taken from src/Illuminate/Testing/AssertableJsonString.php
PHPUnit::assertEquals(
json_encode($expected, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
json_encode($actual, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
);Как было отмечено ранее, json_encode преобразует экземпляр BackedEnum в его строковое значение, поэтому это утверждение пройдёт.
Основной вывод заключается в том, что необходимо знать, как работает ваше утверждение, и строить логику тестирования соответствующим образом, особенно при работе с перечислениями.