PHPUnit:如何测试 returns 无效的 Doctrine Repository 方法?

PHPUnit: How to test Doctrine Repository method that returns void?

我有一个 Doctrine 存储库 class 可以用来持久化一个用户,我不想检查实体是否真的被持久化了,我只是想知道在这方面该做什么情况:

测试具有 return 值 的存储库方法很容易。但在这种情况下,我无事可做,我想覆盖 100% 的代码,而不是像 use @addToAssertionCount.

这样会破坏的不安全代码
<?php

namespace Domain\Repository;

use DateTime;
use Domain\Entity\User;
use Domain\Repository\Interfaces\UserRepositoryInterface;

class UserRepository extends Repository implements UserRepositoryInterface
{
    public function create(User $user): void
    {
        $user->setCreatedAt(new DateTime('now'));

        $this->getEntityManager()->persist($user);
    }
}

并对其进行测试 class:

<?php

namespace Domain\Repository;

use Doctrine\ORM\EntityManager;
use Domain\Entity\User;
use PHPUnit\Framework\TestCase;

class UserRepositoryTest extends TestCase
{
    private UserRepository $sut;

    public function setUp(): void
    {
        $entity_manager = $this->createMock(EntityManager::class);
        $this->sut = new UserRepository($entity_manager);
    }

    public function test_assert_create(): void
    {
        $user = $this->createMock(User::class);
        $this->sut->create($user);

        // What to assert??
    }
}

在这一点上,我什至不知道要断言什么,一旦 persist() 方法 returns void,我无法模拟。

专注于 100% 的代码覆盖率并不是一个好主意,并且会鼓励编写几乎没有价值的测试。那是什么意思? create 方法有两个副作用:它更改了用户的创建日期并将其持久化。你可以这样测试它:

final class UserRepositoryTest extends TestCase
{
    /**
     * @var EntityManager&MockObject
     */
    private EntityManager $entityManager;

    private UserRepository $sut;

    public function setUp(): void
    {
        $this->entityManager = $this->createMock(EntityManager::class);
        $this->sut           = new UserRepository($this->entityManager);
    }

    public function test_create_should_persist_entity(): void
    {
        $user = new User();
        $user->setCreatedAt(new DateTime('2000-01-01 12:15:30'));

        // validate that persist call was made
        $this->entityManager->expects(self::once())
            ->method('persist')
            ->with($user);

        $this->sut->create($user);

        // validate that creation date was set
        self::assertEqualsWithDelta(new DateTime('now'), $user->getCreatedAt(), 3);
    }
}

您甚至可以更进一步,验证创建日期是否在使用回调约束进行持久调用之前设置。但是,您几乎是在测试中逐行检查实现。这就是人们如何结束总是失败的测试。

那么,该怎么做呢?关注用户存储库的目的:如果你把东西放进去,你应该能够把它取出来。但是,这需要您使用实际的实体管理器。但是您写道,您不想检查该实体是否确实持久存在。在那种情况下,我宁愿不写测试也不愿写我上面给出的例子。