Symfony/PhpUnit - 如何测试服务中是不是抛出异常
Posted
技术标签:
【中文标题】Symfony/PhpUnit - 如何测试服务中是不是抛出异常【英文标题】:Symfony/PhpUnit - How to test that an Exception is throws or not in a ServiceSymfony/PhpUnit - 如何测试服务中是否抛出异常 【发布时间】:2021-06-20 10:30:33 【问题描述】:我是测试的初学者,我想测试我的ValidatorService
,当实体数据无效时会抛出InvalidDataException
。
我的 ValidatorServiceTest 函数:
public function testValidatorForUser()
$validatorMock = $this->createMock(ValidatorInterface::class);
$contraintViolationMock = $this->createMock(ConstraintViolationListInterface::class);
$validatorMock->expects($this->once())
->method('validate')
->with()
->willReturn($contraintViolationMock);
$validatorService = new ValidatorService($validatorMock);
$user = new User();
$user->setEmail('test');
$validatorService->validate($user);
$this->expectException(InvalidDataException::class);
我的 ValidatorService :
class ValidatorService
/**
* @var ValidatorInterface
*/
private ValidatorInterface $validator;
public function __construct(ValidatorInterface $validator)
$this->validator = $validator;
/**
* @param $value
* @param null $constraints
* @param null $groups
* @throws InvalidDataException
*/
public function validate($value, $constraints = null, $groups = null)
$errors = $this->validator->validate($value, $constraints, $groups);
if (count($errors) > 0)
throw new InvalidDataException($errors);
我的用户实体:
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @ORM\Table(name="`user`")
* @UniqueEntity(fields="email", errorPath="email", message="user.email.unique")
* @UniqueEntity(fields="username", errorPath="username", message="user.username.unique")
*/
class User implements UserInterface
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private ?int $id;
/**
* @ORM\Column(type="string", length=180, unique=true)
* @JMS\Type("string")
* @JMS\Groups("api")
* @Assert\NotBlank(message="user.email.not_blank")
* @Assert\Email(message="user.email.email")
*/
private string $email;
/**
* @var string The hashed password
* @ORM\Column(type="string")
* @JMS\Type("string")
* @Assert\NotBlank(message="user.password.not_blank")
* @Assert\Length(min=8, minMessage="user.password.length.min")
*/
private string $password;
/**
* @JMS\Type("string")
* @Assert\NotBlank(message="user.confirm_password.not_blank")
* @Assert\EqualTo(propertyPath="password", message="user.confirm_password.equal_to")
*/
private string $confirmPassword;
...
...
我有这个错误:
1) App\Tests\Service\Validator\ValidatorServiceTest::testValidatorForUser
Failed asserting that exception of type "App\Exception\InvalidDataException" is thrown.
如何测试异常是否抛出?
【问题讨论】:
在测试中将调用换成validate()
和 expectException()
- 如果它已经发生了,你就无法期待。
我有同样的错误。
我已经复制了你的代码并尽我所能进行了测试——你没有犯任何错误,$errors 是空的,所以没有抛出任何东西。
我更新了主帖并添加了User
实体。而且我直接用$validator = self::$container->get(ValidatorInterface::class); $errors = $validator->validate($user)
试了一下,$errors 不为空。
【参考方案1】:
已解决:
问题在于我的$contraintViolationMock
,它总是返回空数据。
我必须先检索违规并测试它是否与模拟违规匹配。我认为,这是更简单的解决方案,而不是手动创建ConstraintViolationList
。
如果你有更好的解决方案,我会采纳的。
public function testValidatorForUser()
$user = new User();
$user->setEmail('test');
$validator = self::$container->get(ValidatorInterface::class);
$violations = $validator->validate($user);
$validatorMock = $this->createMock(ValidatorInterface::class);
$validatorMock->expects($this->once())
->method('validate')
->willReturn($violations);
$this->expectException(InvalidDataException::class);
$validatorService = new ValidatorService($validatorMock);
$validatorService->validate($user);
【讨论】:
以上是关于Symfony/PhpUnit - 如何测试服务中是不是抛出异常的主要内容,如果未能解决你的问题,请参考以下文章
测试结束时删除测试数据库(Symfony / PHP Unit)