Symfony,如何编写正确的测试来检查是否有人被删除?

Symfony, How to write a correct test to check if someone is deleted?

在我的 symfony 项目中有一个 PersonController,其函数将 ID 作为参数。 基于该 ID,我必须删除正确的用户。该函数如下所示:

/**
 * @Route("/person/delete", methods={"DELETE"}, name="deletePersonById")
 */
public function deletePersonById(Request $request): JsonResponse
{
    $id = $request->query->get("id");
    $statuscode = 200;
    try {
        $this->personModel->deletePersonById($id);
        $message = "Person with id:" . $id . " deleted";
    } catch (\InvalidArgumentException $exception) {
        $statuscode = 400;
        $message = $exception->getMessage();
    } catch (\PDOException $exception) {
        $statuscode = 500;
        $message = $exception->getMessage();
    }

    return new JsonResponse($message, $statuscode);
}

我可以在 UnitTest 中检查 return 的值吗?目前我认为它 return 的值为 NULL 所以我在我的 unitTest 中做了以下操作:(我不确定这是否是测试它的方法?也许它 return 是一个 201 状态代码删除成功了吗?有什么提示或建议吗?)

/**
 * @dataProvider providerPersons()
 **/
public function testDeletePersonById_personIdInDatabase_Persons($id)
{
    $PersonModel = new PDOPersonModel($this->connection, $this->validator);
    $expectedPersonId = null;
    $actualPersonId = $PersonModel->deletePersonById(strval($id));

    $this->assertEquals($expectedPersonId, $actualPersonId);
}

一个好的开始是清楚地定义人物模型的行为方式。既然你写了“目前我认为它 return 的值为 NULL”,似乎还有一些改进的余地。

我不知道你的人物模型是什么样子的,所以我在这里做点什么:

  • create 应该创建一个人并且 return 它的 id
  • getById 应该 return 具有给定 ID 的人。如果没有那个id的人,它应该抛出一个特定的异常。
  • deleteById 应该删除具有给定 ID 的人。如果没有那个id的人,它应该抛出一个特定的异常。

鉴于此规范,您可以轻松编写测试:删除一个人后,再次尝试检索时应该会出现异常。

与查看数据库以验证它是否已被删除相比,优势在于您可以随心所欲地更改实现和技术,只要它不违反合同。

测试可能如下所示:

final class PersonModelTestCase extends TestCase
{
    private PDOPersonModel $personModel;

    /**
     * @test
     */
    public function a_person_can_be_found_by_its_id()
    {
        $person = new Person('Jane', 'Doe', 'jane@doe.test');

        $id = $this->personModel->create($person);

        self::assertEquals($person, $this->personModel->getById($id));
    }

    /**
     * @test
     */
    public function getById_should_throw_an_exception_if_there_is_no_person_with_the_given_id()
    {
        $invalidId = 'invalid-id';

        self::expectExceptionObject(PersonModelException::notFound($invalidId));

        $this->personModel->getById($invalidId);
    }

    /**
     * @test
     */
    public function after_deleting_a_person_it_can_not_be_found_anymore()
    {
        $id = $this->personModel->create(new Person('Jane', 'Doe', 'jane@doe.test'));

        $this->personModel->deleteById($id);

        self::expectExceptionObject(PersonModelException::notFound($id));
        $this->personModel->getById($id);
    }

    /**
     * @test
     */
    public function deleteById_should_throw_an_exception_if_there_is_no_person_with_the_given_id()
    {
        $invalidId = 'invalid-id';

        self::expectExceptionObject(PersonModelException::deletionFailed($invalidId));

        $this->personModel->deleteById($invalidId);
    }

    protected function setUp(): void
    {
        parent::setUp();

        $this->personModel = new PDOPersonModel($this->connection, $this->validator);
    }
}

但是控制器呢?除了验证 json 响应包含正确的数据外,还有几种方法可以检查此人是否真的被删除。

  1. 基本同上申请即可。如果有删除一个人的动作,我敢打赌也有一个得到一个。
  2. 您可以调用删除操作并验证您无法再通过人员模型获取已删除的人员。
  3. 您可以使用测试模拟切换人员模型实现。