Я использую
Я создал конечную точку 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 Я добавил ContractDataControllerTest выше
(в следующий раз) в этом вопросе также полезно иметь DDL таблицы. судя по вашему ответу, вероятно, уже слишком поздно для этого редактирования, если не считать соображений полноты. DDL может помочь лучше понять (или воспроизвести) проблему.
удалить все файлы в ./var/cache/test/
После этого команда SQL и тест прошли нормально!
Внимание: Удаление всей папки было не лучшей идеей. Теперь другие тесты провалились из-за отсутствия файлов кэша.
Можно это исправить с помощью: php bin/console cache:warmup --env=test
как выглядит код модульного теста?