很不幸地,而且通常大都是不幸的,你正在维护一个legacy 代码,这个legacy code没有完美的"代码-接口"形式,双重测试注入允许存在完美的"代码-接口"。通常,这里在具体对象上有许多详细的依赖项,很难用test doubles代替数据访问对象,以此来模拟现场数据库。在这些情况中,你的选择要么在测试中,refactor legacy code来安装,要么使用一个对象模拟工具(例如:TypeMock)。有了TypeMock,就可能模拟密封的和单一的类型-没有这样一个工具却来实现一个感人的宴会。
Albeit很有力,除非非得需要,不然TypeMock就被放在旁边;过早地使用TypeMock使得不编译接口非常诱人。当操作遗留代码-时间和预算允许时,更正确的方法就是refactor the code,取得更大的灵活性。Michael Feathers的《有效地与遗留代码工作》是包含了很多关于如何在测试工作中重构遗留代码的好办法的书。
NHibernateDAO的单元测试
在这篇文章的前一版本,Nhibernate的ISession通过System.Runtime.Remoting.Messaging.CallContext单例保存和读取。尽管非常适合WinForms 和单元测试,对ASP.NET 来说,却是一个不好的方法,因为ISession 可能在载入时会丢失(这两篇文章给予了进一步的解释:为什么在ASP.NET应用程序里使用CallContext是一个坏的方法)。为了正确地与ASP.NET 应用程序连接,应该将ISession 储存在HttpContext.Current.Items里,但是这样做,当运行单元测试时,会强迫你模拟一个HTTP文本。它同样阻止将结构简单地传递到WinForms。一个更好的方法就是在它正确的时候,使用正确的repository。因此如果一个网页文本可用,然后使用HttpContext;然而,使用CallContext. 将在后面讨论这个结合方式的执行细节。(要感谢许多对这篇文章给予评论,从而引起了这个关注)。阅读与怎样管理ISession有关的
BasicSample.Tests/Data/CustomerDaoTests.cs这篇文章,因为单元测试HTTP-agnostic。一方面,你将在单元测试看到,除非你像在你的测试中改变数据,来服从于数据库,反转处理才是一个好的方法。
正如在示例中显示的,可能创建一个通用的DAO,这个一般的DAO为任何持久稳固的对象工作。(后面将详细讨论)这就引起了应该测试什么以及怎样测试它的争论。每一个具体的DAO都要全面测试吗?怎样维护测试数据?个人经验给出了这些建议:
• 保证每个泛型DAO中的每一个方法都有一个单元测试,例如,如果你有10个实现了泛型Dao的Dao,只有他们其中的一个需要被完全测试。单元测试中的实现了泛型DAO其他9个Dao只会提供很少的附加值。
• 确保每个从泛型Dao扩展的每个方法都有一个单元测试。例如,如果你有一个从泛型DAO继承的CustomerDao 类并且增加了一个方法。如GetActiveCustomers(),那么这个单元测试应该测试这个扩展方法。
• 保证存在一个单元测试来完完全全测试每一个“专业” DAO。例如,DAO BasicSample.Data/HistoricalOrderSummaryDao.cs不是从一般DAO 继承来的,将被看成是一个专业DAO。因此,存在一个单元测试来测试每一个方法。
• 在DAO单元测试被运行之前或者以后,都使用一个工具,例如NDbUnit,把测试数据库放到一个已知的状态。
• 使用如NDbUnit的工具测试数据库在单元测试运行请后的状态。 永远记着,单元测试永远不要依赖另外一个单元测试!他们应该是独立并且可以独立运行。例如一个删除测试不应该依赖上一个插入测试的成功。注意TestFixtureSetUp和其他setup、teardown的方法,保证包含了这个能够独立运行的测试也能够正常运行。
文章来源于领测软件测试网 https://www.ltesting.net/