vb.net – 单元测试具体类
我继承了一个没有接口或抽象类的项目,即只有具体的类,我想引入单元测试.这些类包含许多函数,包含业务逻辑和数据逻辑;打破SOLID的所有规则(
http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29).
我有一个想法.我正在考虑为每个设计不良的类创建接口,公开所有功能.那么至少我可以模拟课程. 我对单元测试比较陌生(我有一个项目经验,在正确的地方使用接口非常发达).这样做是一个好主意,即为所有具体类创建接口(公开所有函数和子例程),仅用于单元测试? 我花了一些时间研究这个,但我没有找到答案. 解决方法
是的,这是一个良好的开端,但是,接口不是注入依赖项的优先级.如果所有遗留类都获得了接口,但内部隐藏它们仍然是相互依赖的,那么这些类仍然不容易测试.例如,假设你有两个看起来像这样的类:
Public Class LegacyDataAccess Public Function GetAllSales() As List(Of SaleDto) ' Do work with takes a long time to run against real DB End Function End Class Public Class LegacyBusiness Public Function GetTotalSales() As Integer Dim dataAccess As New LegacyDataAccess() Dim sales As List(Of SaleDto) = dataAccess.GetAllSales() ' Calculate total sales End Function End Class 我知道你已经在说什么……“我希望遗留代码至少能够很好地分层”,但是让我们将其作为一些难以测试的遗留代码的例子.难以测试的原因是代码到达数据库并对数据库执行耗时的查询,然后从中计算结果.因此,为了在当前状态下测试它,您需要首先将一堆测试数据写入数据库,然后运行代码以查看它是否根据插入的数据返回正确的结果.必须编写类似的测试是有问题的,因为: >编写代码来设置测试是一件痛苦的事 正如您所正确观察的那样,接口对于单元测试非常重要.因此,正如您所建议的那样,让我们??添加接口以查看它是否更容易测试: Public Interface ILegacyDataAccess Function GetAllSales() As List(Of SaleDto) End Interface Public Interface ILegacyBusiness Function GetTotalSales() As Integer End Interface Public Class LegacyDataAccess Implements ILegacyDataAccess Public Function GetAllSales() As List(Of SaleDto) _ Implements ILegacyDataAccess.GetAllSales ' Do work with takes a long time to run against real DB End Function End Class Public Class LegacyBusiness Implements ILegacyBusiness Public Function GetTotalSales() As Integer _ Implements ILegacyBusiness.GetTotalSales Dim dataAccess As New LegacyDataAccess() Dim sales As List(Of SaleDto) = dataAccess.GetAllSales() ' Calculate total sales End Function End Class 所以现在我们有接口,但实际上,它如何使它更容易测试?现在我们可以轻松地创建一个模拟数据访问对象,它实现了相同的接口,但这并不是核心问题.问题是,我们如何让业务对象使用该模拟数据访问对象而不是真实的?要做到这一点,您需要通过引入依赖注入将重构提升到一个新的水平.真正的罪魁祸首是业务类的以下行中的New关键字: Dim dataAccess As New LegacyDataAccess() 业务类明显依赖于数据访问类,但目前它隐藏了这一事实.这是关于它的依赖性.它说,来吧,这很容易,只需调用此方法,我将返回结果 – 这就是所需要的.真的,它需要更多.现在,让我们说,我们阻止它说谎它的依赖关系,并使它如此毫不掩饰地声明它们,如下所示: Public Class LegacyBusiness Implements ILegacyBusiness Public Sub New(dataAccess As ILegacyDataAccess) _dataAccess = dataAccess End Sub Private _dataAccess As ILegacyDataAccess Public Function GetTotalSales() As Integer _ Implements ILegacyBusiness.GetTotalSales Dim sales As List(Of SaleDto) = _dataAccess.GetAllSales() ' Calculate total sales End Function End Class 现在,正如您所看到的,这个类更容易测试.我们不仅可以轻松创建模拟数据访问对象,而且现在我们可以轻松地将模拟数据访问对象注入到业务对象中.现在我们可以创建一个模拟器,它可以快速轻松地返回我们想要返回的数据,然后查看业务类是否返回正确的计算 – 不涉及数据库. 不幸的是,虽然向现有类添加接口是轻而易举的,但重构它们以使用依赖注入通常需要更多的工作.您可能需要计划哪些类最有意义才能首先解决.您可能需要创建一些中间旧学校包装器,它们按照代码的方式工作,因此您在重构代码的过程中不会破坏现有代码.这不是一件快速而简单的事情,但是如果你有耐心并长期坚持下去,就有可能做到这一点,你会很高兴你做到了. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |