考虑以下停止服务的方法:
Public Function StopService(ByVal serviceName As String, ByVal timeoutMilliseconds As Double) As Boolean
Try
Dim service As New ServiceController(serviceName)
Dim timeout As TimeSpan = TimeSpan.FromMilliseconds(timeoutMilliseconds)
service.[Stop]()
If timeoutMilliseconds <= 0 Then
service.WaitForStatus(ServiceControllerStatus.Stopped)
Else
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout)
End If
Return service.Status = ServiceControllerStatus.Stopped
Catch ex As Win32Exception
'error occured when accessing a system API'
Return False
Catch ex As TimeoutException
Return False
End Try
End Function
为了对该方法进行单元测试,我基本上有两种选择:
- 使用适配器模式来包装
ServiceController
我需要将类的方法放入我可以控制的接口中。然后可以将该接口注入到服务类中(也称为控制反转)。这样我就有了松散耦合的代码,并且可以使用传统的模拟框架来测试。
- 保持类原样并使用
Microsoft Moles(或任何其他代码
绕行框架)拦截
的电话
ServiceController
到
返回测试结果
目的。
我同意,对于域模型代码,使用“传统”单元测试方法最有意义,因为这将导致最容易维护的设计。然而,对于处理 Windows API 相关内容(文件系统、服务等)的 .net 实现的代码,通过额外的工作来获取“传统”可测试代码真的有优势吗?
我很难看出使用 Microsoft Moles 进行以下操作的缺点ServiceController
(或者File
目的)。在这种情况下,我真的看不出采用传统方法有任何优势。我错过了什么吗?
顺便说一句,很好的问题..现在刚刚看了 MS Moles 视频。尽管我对 MS 单元测试工具持怀疑态度,但我必须说这个工具看起来很有趣。我的比较是:
适配器/外观
- 优点:允许您通过意图揭示方法提取有意义的角色。例如
ServiceManager.StartService(name)
可以抽象细节{1. ServiceController.GetServices(), 2. 处理 ServiceController.Status != Stopped 的情况,3. ServiceController.Start()}。这里的模拟/假方法比设置 3 个代表需要更少的工作。这种方法是通过提出有意义的契约/接口来改进设计的机会(还允许您隐藏您不关心的东西——例如 Winapi 语义、常量等)
- 优点:模拟框架将为您提供更好的参数检查诊断、调用次数、未调用的期望等。
拦截器
- 优点:如果您只是感兴趣,则工作量会减少消除对依赖项的有问题的调用
- 优点:在处理遗留代码时(对变化的恐惧是压倒性的),绝对是你工具箱中的一个好工具
- 缺点:它有 MSTest 依赖性吗?初步搜索似乎表明,如果您不使用 MSTest,则需要一些插件或扩展。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)