gpt4 book ai didi

unit-testing - 我应该在单元测试方面走多远?

转载 作者:行者123 更新时间:2023-12-03 14:40:45 25 4
gpt4 key购买 nike

我正在尝试像一个优秀的小程序员一样在个人 PHP 项目中进行单元测试,并且我想正确地做到这一点。据我所知,您应该测试的只是方法的公共(public)接口(interface),但我想知道这是否仍然适用于下面。

我有一种方法可以在用户忘记密码时生成密码重置 token 。该方法返回以下两种情况之一:如果一切正常,则返回无(null),或者表示具有指定用户名的用户不存在的错误代码。

如果我只测试公共(public)接口(interface),如果用户名有效,我如何确保密码重置 token 进入数据库,如果用户名无效,则不进入数据库?我应该在我的测试中进行查询以验证这一点吗?还是我应该假设我的逻辑是合理的?

现在这个方法非常简单,这没什么大不了的——问题是同样的情况也适用于许多其他方法。你在以数据库为中心的单元测试中做什么?

代码,供需要时引用:

public function generatePasswordReset($username)
{
$this->sql='SELECT id
FROM users
WHERE username = :username';

$this->addParam(':username', $username);
$user=$this->query()->fetch();

if (!$user)
return self::$E_USER_DOESNT_EXIST;
else
{
$code=md5(uniqid());
$this->addParams(array(':uid' => $user['id'],
':code' => $code,
':duration' => 24 //in hours, how long reset is valid
));

//generate new code, delete old one if present
$this->sql ='DELETE FROM password_resets WHERE user_id=:uid;';
$this->sql.="INSERT INTO password_resets (user_id, code, expires)
VALUES (:uid, :code, now() + interval ':duration hours')";

$this->execute();
}
}

最佳答案

至少对我来说,单元测试的伟大之处在于它向您展示了您需要重构的地方。使用上面的示例代码,您基本上在一种方法中发生了四件事:

//1. get the user from the DB
//2. in a big else, check if user is null
//3. create a array containing the userID, a code, and expiry
//4. delete any existing password resets
//5. create a new password reset

单元测试也很棒,因为它有助于突出依赖关系。如上所示,此方法依赖于 DB,而不是实现接口(interface)的对象。这种方法与它范围之外的系统交互,实际上只能用集成测试来测试,而不是单元测试。单元测试用于确保工作单元的工作/正确性。

考虑 Single Responsibility Principle :“ Do one thing”。它适用于方法和类。

我建议您的 generatePasswordReset方法应该重构为:
  • 给定一个预定义的现有用户对象/ID。在此方法之外进行所有这些健全性检查。做一件事。
  • 将密码重置代码放入自己的方法中。这将是一个单独的工作单元,可以独立于 SELECT 进行测试。 , DELETEINSERT .
  • 创建一个可以称为 OverwriteExistingPwdChangeRequests() 的新方法这将负责删除 + 插入。
  • 关于unit-testing - 我应该在单元测试方面走多远?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1200137/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com