9. Mock Object 사용 예(1/3) UserRegister를 구현, User 암호 저장 기능에 대한 테스트 class UserRegister { public: UserRegister() {}; ~UserRegister() {}; void SavePassword(const std::string& user_id, const std::string& user_pwd) { user_pwd_table_[user_id] = user_pwd; } std::string GetPassword(const std::string& user_id) { std::map<std::string, std::string>::iterator it = user_pwd_table_.find(user_id); assert(it != user_pwd_table_.end()); return it->second; } private: std::map<std::string, std::string> user_pwd_table_; }; TEST(PasswordTest, password_ciper_test) { UserRegister* user_register = new UserRegister(); std::string user_id = "aether"; std::string user_pwd = "potato"; user_register->SavePassword(user_id, user_pwd); EXPECT_EQ(user_pwd, user_register->GetPassword(user_id)); } 테스트 성공!!
10. Mock Object 사용 예(2/3) 요구 사항 – 사용자 암호는 반드시 암호화한 다음에 저장해야 한다 class Cipher { public: Cipher(); ~Cipher(); virtual std::string Encryption(const std::string& source)=0; virtual std::string Decryption(const std::string& source)=0; }; MD5 기반으로 다른 개발자가 독립적으로 구현하기로.. TEST(PasswordTest, password_ciper_test) { UserRegister* user_register = new UserRegister(); // Ciper* ciper = ... 이거 만들어주면되는데.. std::string user_id = "aether"; std::string user_pwd = "potato"; user_register->SavePassword(user_id, cipher->Encryption(user_pwd)); std::string decripted_pwd = cipher->Decryption(user_register->GetPassword(user_id)); EXPECT_EQ(user_pwd, decripted_pwd); } 테스트 코드를 통과시켜야 하는데............... 다른 개발자가 MD5를 기반으로 Cipher를 만들어 줄 때까지 기다려야 하는가?
11. Mock Object 사용 예(3/3) MD5Cipher처럼 보이는 객체를 만들어서 사용하자. class MockMD5Cipher : public Cipher { public: MockMD5Cipher() {}; ~MockMD5Cipher() {}; virtual std::string Encryption(const std::string& source) { return "8ee2027983915ec78acc45027d874316“; } virtual std::string Decryption(const std::string& source) { return "potato“; } }; TEST(PasswordTest, password_ciper_test) { UserRegister* user_register = new UserRegister(); Cipher* cipher = new MockMD5Cipher(); std::string user_id = "aether"; std::string user_pwd = "potato"; user_register->SavePassword(user_id, cipher->Encryption(user_pwd)); std::string decripted_pwd = cipher->Decryption(user_register->GetPassword(user_id)); EXPECT_EQ(user_pwd, decripted_pwd); } MockMD5Cipher의 구현자체는 임시적이겠지만, 정말 구현하려고 하는 SavePassword기능을 테스트 케이스로 만들기에는 충분한 코드이다.
12. 언제 Mock Object를 만들 것인가? 모듈이 가진 의존성이 근본적인 원인 모듈이 필요로 하는 의존성은 테스트 작성을 어렵게 만든다.