Are Using Interfaces Soley to Facilitate Stubing and Mocking in Unit Tests Now Obsolete?(使用 Soley 接口来促进单元测试中的 Stubing 和 Mocking 现在已经过时了吗?)
问题描述
在 .NET 中,TypeMock Isolator 和 Microsoft Moles 允许隔离任何类、属性或方法 - 无论是密封的、静态的、受保护的还是非虚拟的.所以在 Moq 或 Rhino Mocks 中不可能模拟的东西,现在不再是这样了.
In .NET, TypeMock Isolator and Microsoft Moles allow one to isolate any class, property, or method - be it sealed, static, protected or non-virtual. So what was impossible to mock in Moq or Rhino Mocks, now no longer is the case.
我一直对使用接口只是为了能够允许模拟的想法有些反感,否则只会存在具体的类.我并不孤单(请参阅此处,这里和这里).在后面,它暗示现代"模拟框架不再需要用于测试或依赖注入的接口.
I've always had some aversion with the idea of using an interface merely to be able to allow for mocking, when otherwise just the concrete class would exist. I'm not alone in this view (see here, here, and here). In the later it's implied that 'modern' mocking frameworks no longer need interfaces for testing or dependency injection.
但是,虽然我不能代表 TypeMock Isolator,但我可以说在 Microsoft Moles 中使用 Mocks 非常慢.在单元测试中使用如下代码会导致测试速度太慢而不能经常使用:
However, while I can't speak for TypeMock Isolator, I can say that using Mocks in Microsoft Moles is extremely slow. Having code like the following in unit tests makes the speed of the test too slow to be used often:
MFile.ReadAllLinesString = (s) => csvDataCorrectlyFormatted;
MDirectoryInfo.AllInstances.GetFilesString = (di,fi) => fileInfoArray;
MFileInfo.AllInstances.NameGet = (fi) => "Doesn't Matter";
我敢肯定,如果正在测试的方法被编程为接口或抽象基类(以便文件系统代码可以在某种包装器中抽象出来),那么使用 Moq 之类的框架进行存根或模拟将会结束起来更快.但是我们又回到了为基本单元测试能力增加生产代码复杂性的情况.
I'm sure that if the method being tested was programmed to an interface or abstract base class (so that the file system code could be abstracted away in a wrapper of sorts) that using frameworks like Moq for stubbing or mocking would end up being faster. But then we are back to the situation of having added production code complexity for basically the ability to unit test.
我倾向于认为 Isolator 和 Moles 只有在无法使用传统的模拟框架进行模拟时才应使用.然而,我仍然在为测试而增加生产代码复杂性的想法苦苦挣扎.
I'm leaning to the opinion that Isolator and Moles should only be used when one can't mock with traditional mocking frameworks. Yet, I still struggle with notion of having added production code complexity for the sake of testing.
我很好奇社区其他人的想法.
I'm curious what the rest of the community thinks.
2010 年 6 月 10 日更新:我说我在为测试而增加生产代码复杂性的概念上苦苦挣扎,我指的是添加一个接口(或抽象类甚至)在不需要的情况下,例如在使具体类为非密封并且方法为虚拟时会这样做.后者仍然允许接缝进行测试.即使后来发现需要为多个实现使用一个接口,他们难道不能从类中提取它吗?但除非出现这种需要,否则为什么不关注 YAGNI.
UPDATE 10/06/10: By saying I struggle with the notion of having added production code complexity for the the sake of testing, I'm referring to the adding an interface (or abstract class even) when otherwise one isn't needed, such as when making the concrete class non-sealed and methods virtual would do. The latter still allows seams for testing. Even if later one finds the need to use an interface for multiple implementations, couldn't they extract it from the class? But unless that need arises, why not follow YAGNI.
我完全赞成 SOLID 原则,它们使程序的架构更易于维护.我不认为在任何情况下都需要虔诚地遵循这些原则.我认为它总是取决于"的口头禅多次发挥作用.否则,每个具体类型都有一个接口或抽象基类,即使只有一个实现.
I'm all for the SOLID principles where they make the architecture of a program easier to maintain. I don't think these principles need to be followed religiously in every case. I think the mantra, "It always depends", comes into play many times. Otherwise, one is left with every concrete type having an interface or abstract base class, even when there will be only one implementation.
最后,我并不是说,因为 Isolator 和 Moles 允许人们绕过基于动态代理的框架中的隔离限制,人们不应该将架构设计为可维护的.在许多情况下,SOLID 原则是最好的,因此不需要隔离器或 Moles.我质疑的是界面仅用于测试的情况.我也提出了另一个关于速度的观点.如果一个人选择使用隔离器和鼹鼠,它似乎会带来速度惩罚.所以我当然不认为他们会淘汰基于动态代理的框架.
Lastly, I'm not saying that because Isolator and Moles allows one to get around isolation limitations in dynamic-proxy-based frameworks that one shouldn't still design architecture to be maintainable. In many cases, the SOLID principles are what is best, and thus Isolator or Moles wouldn't be needed. It's the cases where the interface is used solely for testing that I am questioning. I'm bringing up another side point about speed too. If one chooses to use Isolator and Moles it appears to bring a speed penalty. So I certainly don't think that they make dynamic-proxy-based frameworks obsolete.
推荐答案
一点也不.从纯粹的技术角度来看,这些接口并不是绝对必要的.模拟框架构造模拟的唯一要求是方法是虚拟的并且类型具有可访问的构造函数.当我知道一个特定的类不会有多个实现时,我会使用它.
Not at all. From a purely technical point of view the interfaces are not strictly necessary. The only requirement for a mocking framework to construct a mock is that a method is virtual and the type has an accessible constructor. I utilize it quite a bit when I know that a particular class will not have multiple implementations.
我更喜欢使用基于普通 Castle Dynamic Proxy 的模拟框架进行 TDD.这一切都是为了创建一个松散耦合的系统,其中包含适当放置的测试接缝.这些测试接缝将来可能成为可扩展点.模拟考虑所提出的要求强化了良好的设计实践,导致编写更集中的类.
I prefer doing TDD with a normal Castle Dynamic Proxy based mocking framework. It is all about creating a loosely coupled system with appropriately placed testing seams. Those testing seams could in future become extensibility points. The requirements placed by mocking considerations reinforce good design practices, causing more focused classes to be written.
这篇关于使用 Soley 接口来促进单元测试中的 Stubing 和 Mocking 现在已经过时了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Soley 接口来促进单元测试中的 Stubing 和 Mo
基础教程推荐
- rabbitmq 的 REST API 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- 如何激活MC67中的红灯 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01