我试图在个人PHP项目中进行单元测试,就像一个好的小程序员一样,我想正确地做到这一点。从我听到的你应该测试的只是方法的公共接口,但我想知道这是否仍然适用于下面。单元测试应该走多远?
我有一种方法可以在用户忘记密码的情况下生成密码重置令牌。该方法返回以下两种情况之一:如果一切正常,则返回nothing(null),或者返回错误代码,表示具有指定用户名的用户不存在。
如果我只测试公共接口,如果用户名是有效的,如何确保密码重置标记进入数据库,并且如果用户名无效则不会进入数据库?我应该在我的测试中进行查询以验证这一点吗?或者我应该认为我的逻辑是正确的?
现在这种方法非常简单,这不是什么大问题 - 问题是这种情况也适用于其他许多方法。你在以数据库为中心的单元测试中做什么?如果需要的话
代码,以供参考:
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();
}
}
对于我来说,至少对单元测试来说,伟大之处在于它向您展示了您需要重构的地方。它还有助于突出显示依赖关系。我建议你的`SELECT`和你的`DELETE + INSERT`应该被重构到它们自己的方法中,密码的生成应该在它自己的方法中 – 2009-07-29 13:14:02
@pcampbell - 你的评论应该是一个答案 – 2009-07-29 13:17:36