我試圖在個人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