Странное поведение доктрины Symfony во время теста phpunit - поле в базе данных становится нулевым

Я использую

  • Симфония v6.4.8
  • доктрина/форма 2.19.5
  • phpunit/phpunit 9.6.19

Я создал конечную точку GET REST API /api/contract/{$id} в Symfony.

Он выполняет запрос API в другой системе, получает эти данные, объединяет их с данными локальной базы данных и создает новую запись в моей базе данных.

У меня проблема в том, что в / после persist()/flush() в базе данных иногда поле $contract->eup находится NULL в базе данных.

eup определяется как nvarchar(10) в базе данных MSSQL.

private function saveContract(EntityManager $em, array $data): ContractData
{        
    $contract = new ContractData();
    // [... some more variables]
    $contract->setEup($data['eup']);  // example: "2024-06-29"
    
    $em->persist($contract);
    $em->flush();

    return $contract;
}

Обновление: упрощенный код теста phpunit:

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class ContractDataControllerTest extends WebTestCase
{
    public static function contractProvider(): array
    {
        $testCases = array(
            ['18fac35b-4afe-476e-9094-1437deeb6f0a', 'stringValue1', '2024-06-29'],
        );
        return $testCases;
    }
    
    /**
     * @covers \App\Controller\API\ContractDataController::contract
     * @dataProvider contractProvider
     */
    public function testGetContractWhileLoggedIn($id, $expectValue1, $expectEup): void
    {
        $uri = $this->getUriWithSignature('/api/contract/', $id);

        $client = static::createClient();
        $client->disableReboot();
        $client->setServerParameter('HTTP_Authorization', 'Bearer ' . $_ENV['TOKEN']);
        $client->request('GET', $uri);

        $this->assertResponseStatusCodeSame(200);

        $responseData = json_decode($client->getResponse()->getContent(), true);

        $this->assertSame($expectValue1, $responseData['value1']);
        // the other values are working, there are more values to test, code is simplyfied, only eup is empty at database.
        $this->assertSame($expectEup, $responseData['valueEup']); 
    }
}

Когда я вызываю свой API с помощью Postman, запись создается правильно, а поле eup в базе данных заполняется строкой.

Но когда я запускаю тест phpunit php bin/phpunit --filter myTest, он вызывает API, запись создается в базе данных, но поле eup — это NULL.

  • Остальные поля этой записи при тесте сохраняются корректно.

  • Также возможно записать значение этого поля в другие поля.

  • Также пробовал использовать более короткую строку, но это тоже не сохраняется.

  • Я также запустил тест с помощью xdebug и могу подтвердить (вместе с моим коллегой), что $contract->eup установлено и заполнено строкой в ​​$em->persist($contract);, но когда мы смотрим после сброса в базе данных SELECT * FROM ..., поле eup равно NULL.

У вас есть идеи, что может быть не так?

Обновление2: Я обновил конфигурацию регистратора/packages/monolog.yaml.

# add Doctrine-Handler
        doctrine:
            type: stream
            path: '%kernel.logs_dir%/doctrine.log'
            level: debug
            channels: ["doctrine"]

Там я обнаружил, что SQL INSERT INTO — это не то, что я ожидаю: Executing statement: INSERT INTO contract_data (contract_number) VALUES (?) (parameters: array{"1":"XYZ123456"}, types: array{"1":2}) Поле eup отсутствует в команде SQL!

Однако я не знаю, что изменить, чтобы это поле использовалось там.

как выглядит код модульного теста?

duncan 28.06.2024 12:46

@duncan Я добавил ContractDataControllerTest выше

SvenW 28.06.2024 13:22

(в следующий раз) в этом вопросе также полезно иметь DDL таблицы. судя по вашему ответу, вероятно, уже слишком поздно для этого редактирования, если не считать соображений полноты. DDL может помочь лучше понять (или воспроизвести) проблему.

hakre 07.07.2024 00:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
3
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мое решение проблемы с SQL:

удалить все файлы в ./var/cache/test/

После этого команда SQL и тест прошли нормально!

Внимание: Удаление всей папки было не лучшей идеей. Теперь другие тесты провалились из-за отсутствия файлов кэша.

Можно это исправить с помощью: php bin/console cache:warmup --env=test

Другие вопросы по теме