Когда мы пишеем тесты на бэкенд-путь, который возвращает данные с отношениями, ($order
, в нём $order→user
, в нём $order→user→plan
и т.д.) — следует избегать проверять отсутсвие тех или иных id через assertJsonMissing(['id' => $order2->id])
и ему подобные методы. Когда тестов окажется много, и мы их запустим разом, инкремент-айдишники в таблицах побегут и в какой-то момент внутри $order
, который в json есть, внезапно окажется $user
у которого id такой же как у $order2
, и тест не пройдет.
Имеется в виду запуск всего пакета тестов, например, в Laravel с включенным трейтом RefreshDatabase: таблицы БД после каждого теста чистятся, но структура заново не пересоздается. Это и быстрее, и более похоже на «живую» среду.
И мы будем голову ломать, почему вдруг этот тест сломался на ровном месте и почему это проявляется, только если сразу все тесты запустить. И ладно мы, мы-то быстро найдем почему. А вот если мы работаем с ИИ, он половину рабочего кода искромсает своми правками, пока допрёт, что это было. Если допрёт вообще — мой вот не допёр.
В общем, проверять json ответа без декодирования в массивы/объекты не очень хорошо, т.к. может повлечь подобные ложные мэтчи.
Неправильно:
$response->assertJsonMissing(['id' => $order2->id]);
Этот код будет искать по содержимому всего json и рано или поздно найдет вложенную зависимость со случайно совпавшим id.
Правильнее будет например:
$data = $response->decodeResponseJson('data');
$this->assertNotContains($order2->id, array_map(function ($order) {
return $order['id'];
}, $data););
// так мы явно показываем, на каком уровне вложенности тестируем
// также можно использовать замыкания внутри assertJson(), позволяющие ходить по уровням структуры документа