我有一个列,它是 DateTimeImmutable,当用户加入平台时保存。我正在进行 phpunit 测试,我想验证该列是否无法更新。我想在出现 SQL 错误(尝试更新列时出错)之前检测到错误。
#[ORM\Column(updatable: false)]
#[Assert\Type(
type: 'object',
message: 'The value {{ value }} is not a valid {{ type }}.'
)]
private ?\DateTimeImmutable $joinedAt = null;
我尝试更新实体列,然后调用 $manager->persist($entity) 看看当时是否有错误,但没有任何反应。
public function testInvalidJoinedAt(): void
{
$manager = static::getContainer()->get(EntityManagerInterface::class);
// User joinedAt cannot be updated
$now = new DateTimeImmutable();
$existingUser = $this->getRepository(UserRepository::class)->find(0);
$existingUser->setJoinedAt($now);
try {
$manager->persist($existingUser);
} catch (\Throwable $err) {
$this->assertEquals('???', $err->getMessage());
}
}
像“#[Assert\NotUpdatable]”这样的断言类型将是完美的解决方案,但没有这样的东西。
您可以创建自己的自定义验证器,在此处查看文档在此处输入链接描述 在你的 src/Validator/Constraints 添加文件 1)
class fileName extends Constraint
{
public $message = 'Error Message Goes here for not modifd property';
}
class FileName extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if ($value !== null) {
$this->context->buildViolation($constraint->message)->addViolation();
}
}
}
您可以将自定义验证器添加到实体断言中
/**
* @ORM\Column(updatable=false)
* @customValidator\validatorName
*/
private ?\DateTimeImmutable $joinedAt = null;
Doctrine 不验证 Symfony Validation 属性。在保存之前,您必须使用 Symfony 验证器验证实体。
使用自定义验证器,您需要知道它是插入还是更新,因为 Symfony 验证器不知道您是在执行插入还是更新。这样就可以创建这样一个自定义验证器。但这是一个更大的努力。
我会根据你的方法解决它
testInvalidJoinedAt()
所以你不必验证。
namespace App\Entity;
use Doctrine\ORM\Mapping\Column;
class Entity
{
#[Column(updatable: false)]
private ?\DateTimeImmutable $joinedAt = null;
public function getJoinedAt(): ?\DateTimeImmutable
{
return $this->joinedAt;
}
public function setJoinedAt(?\DateTimeImmutable $joinedAt): void
{
if (!$this->joinedAt instanceof \DateTimeImmutable) {
$this->joinedAt = $joinedAt;
}
}
}
单元测试示例
class EntityTest extends TestCase
{
public function testNewEntity() {
$dateTime = new DateTimeImmutable();
$entity = new Entity();
$entity->setJoinedAt($dateTime);
$this->assertEquals($dateTime, $entity->getJoinedAt());
}
public function testEntityFromDatabase() {
// Mock entity from database
$dateTime = new DateTimeImmutable();
$dateTime->setDate(2022, 9, 17)->setTime(19, 31, 41);
$entityFromDatabase = new Entity();
$entityFromDatabase->setJoinedAt($dateTime);
// Set joinedAt update
$entityFromDatabase->setJoinedAt(
(new DateTimeImmutable())->setDate(2023, 10, 19)->setTime(8, 11, 15)
);
$this->assertEquals($dateTime, $entityFromDatabase->getJoinedAt());
}
}