TDD学习笔记【四】--- 如何隔离相依性 - 基本的…
2018-06-17 20:19:56来源:未知 阅读 ()
前言
什么是相依性
- 根据 id,取得存在数据源中的密码(仅存放经过 hash 运算后的结果)。
- 根据传入的密码,进行 hash 运算。
- 比对数据源回传的密码,与输入密码经过哈希运算的结果,是否吻合。
简单的程序代码如下(AccountDao与Hash的内容不是重点,为节省篇幅就先省略):
1 using System; 2 3 public class Validation 4 { 5 public bool CheckAuthentication(string id, string password) 6 { 7 // 取得数据库中,id对应的密码 8 AccountDao dao = new AccountDao(); 9 var passwordByDao = dao.GetPassword(id); 11 // 针对传入的password,进行hash运算 12 Hash hash = new Hash(); 13 var hashResult = hash.GetHashResult(password); 15 // 对比hash后的密码,与数据库中的密码是否吻合 16 return passwordByDao == hashResult; 17 } 18 } 19 20 public class AccountDao 21 { 22 internal string GetPassword(string id) 23 { 24 //连接DB 25 throw new NotImplementedException(); 26 } 27 } 28 29 public class Hash 30 { 31 internal string GetHashResult(string passwordByDao) 32 { 33 //使用SHA512 34 throw new NotImplementedException(); 35 } 36 }
相依性的问题
单元测试的角度
[TestMethod()] public void CheckAuthenticationTest() { Validation target = new Validation(); // TODO: 初始化为适当值 string id = string.Empty; // TODO: 初始化为适当值 string password = string.Empty; // TODO:初始化为适当值 bool expected = false; // TODO: 初始化为适当值 bool actual; actual = target.CheckAuthentication(id, password); Assert.AreEqual(expected, actual); Assert.Inconclusive("验证这个测试方法的正确性。"); }
弹性设计的角度
如何隔离对象之间的相依性
1 public interface IAccountDao 2 { 3 string GetPassword(string id); 4 } 5 6 public interface IHash 7 { 8 string GetHashResult(string password); 9 } 10 11 public class AccountDao : IAccountDao 12 { 13 public string GetPassword(string id) 14 { 15 throw new NotImplementedException(); 16 } 17 } 18 19 public class Hash : IHash 20 { 21 public string GetHashResult(string password) 22 { 23 throw new NotImplementedException(); 24 } 25 } 26 27 public class Validation 28 { 29 private IAccountDao _accountDao; 30 private IHash _hash; 31 32 public Validation(IAccountDao dao, IHash hash) 33 { 34 this._accountDao = dao; 35 this._hash = hash; 36 } 37 38 public bool CheckAuthentication(string id, string password) 39 { 40 // 取得数据库中,id对应的密码 41 var passwordByDao = this._accountDao.GetPassword(id); 42 // 针对传入的password,进行hash运算 43 var hashResult = this._hash.GetHashResult(password); 44 // 对比hash后的密码,与数据库中的密码是否吻合 45 return passwordByDao == hashResult; 46 } 47 }
控制反转(IoC),它为相互依赖的组件提供抽象,将依赖(低层模块)对象的获得交给第三方(系统)来控制,即依赖对象不在被依赖模块的类中直接通过new来获取依赖注入(DI),它提供一种机制,将需要依赖(低层模块)对象的引用传递给被依赖(高层模块)对象。
原文可參考 Martin Fowler 的文章:Inversion of Control Containers and the Dependency Injection pattern
As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.
如何进行测试
[TestMethod()] public void CheckAuthenticationTest() { IAccountDao accountDao = null;// TODO: 初始化为合适的值 Hash hash = null;// TODO: 初始化为合适的值 Validation target = new Validation(accountDao, hash); string id = string.Empty; // TODO: 初始化为合适的值 string password = string.Empty;//TODO: 初始化为合适的值 bool expected = false;// TODO: 初始化为合适的值 bool actual; actual = target.CheckAuthentication(id, password); Assert.AreEqual(expected, actual); Assert.Inconclusive("验证这个测试的正确性。"); }
public class StubAccountDao : IAccountDao { public string GetPassword(string id) { return "Hello World"; } }
接着用同样的方式,让 StubHash 的 GetHashResult,也回传 "Hello World",代表 hash 后的结果。程序代码如下:
public class StubHash : IHash { public string GetHashResult(string password) { return "Hello World"; } }
聪明的读者朋友们,应该知道接下来就是来写单元测试的 3A pattern,单元测试程序代码如下:
[TestMethod()] public void CheckAuthenticationTest() { //arrange // 初始化StubAccountDao,来当作IAccountDao的执行对象 IAccountDao dao = new StubAccountDao(); // 初始化StubHash,来当作IStubHash的执行对象 IHash hash = new StubHash(); Validation target = new Validation(dao, hash); string id = "随便写"; string password = "随便写"; bool expected = true; bool actual; //act actual = target.CheckAuthentication(id, password); //assert Assert.AreEqual(expected, actual); }
延伸思考
结论
补充
备注:这个系列是我毕业后时隔一年重新开始进入开发行业后对大拿们的博文摘要整理进行学习对自我的各个欠缺的方面进行充电记录博客的过程,非原创,特此感谢91 等前辈
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Delphi10.3的ListView学习(大图标) 2020-06-05
- Delphi10.3的SpeedButton/BitBtn学习 2020-06-05
- uniGUI学习之UniStringGrid(35) 2020-04-15
- uniGUI学习之uniButton图标(34) 2020-04-09
- UniGUI学习之hbox布局(33) 2020-04-08
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash