.NET平台测试驱动开发模拟框架Moq简明教程(简介)<转>

简介:

一、简介

目前针对测试驱动开发技术的研究在国内看来还少得可怜,估计这主要是国内的软件开发实际所致(急功近利型颇多)。所以,针对目前比较优秀的测试框架以及模拟框架的介绍也不多见。鉴于此,我想借这篇短文,对目前.NET平台上最新出炉的模拟对象框架—Moq作一简介。Moq的发明者声称,较之于其他的模拟对象框架(例如Rhino Mocks和TypeMock Isolator),这个框架更易于学习和使用。

具体来看,Moq框架中充分利用了VB.NET和C#语言的最新特征,例如lambda表达式与泛型的概念。因此,当你使用Moq创建模拟对象时,你可以使用lambda表达式来描述你想要模拟的方法与属性等。由于提供了对于最新的lambda表达式的支持,Moq得以能够提供一种格外清晰的语法形式来描述期望值、参数约束和返回值等。

根据Moq的作者的说法,你可以把“Moq”发音为“Mock-You”或者干脆与“Mock”一致。名称“Moq”源于Mock和Linq的组合。既然Moq使用的是lambda表达式而不是Linq表达式,所以名字“Mambda”似乎更为准确一些。

Moq框架的维护者为Daniel Cazzulino。你可以阅读Daniel Cazzuiono关于Moq的博客入口:
http://www.clariusconsulting.net/blogs/kzu/archive/category/1062.aspx。

本文中我们集中讨论的是Moq的2.5版本,其实这并不是最新的(例如下文图中给出的2.5.3版本下载后的文件名字),但是基本代表了这个框架的最新特征。

二、背景与争论

关于模拟框架的使用,一直以来存在一些争论。目前在.NET平台上主要存在三个流行的Mock框架,它们分别是:Typemock Isolator,Rhino Mocks和Moq。其中,TypeMock Isolator因其功能过于强大而受到批评;相反地,Moq也因过于简单也受到同样的批评。为什么会存在这种看似荒诞的批评呢?

一些人批评Typemock Isolator的功能过于强大。批评者认为,TypeMock Isolator可能会导致鼓励糟糕的软件设计,因为你有可能使你在代码框架的设计方面产生惰性,理由是编写可模拟的代码应该能够迫使开发者编写出更良好的代码。现在的情形是,Typemock Isolator能够支持你模拟出任何东西,甚至是你想模拟的一切。因此,批评者认为,这个工具并没有把开发者引导到良构代码的编写道路上。他们甚至还打了另一个比方,说Typemock Isolator就像把一个核武器交给一个仅仅四岁的小孩使用一样。

在Typemock Isolator被批评其功能过于强大的同时,Moq则被批评其功能过于简单。抱怨者认为,Moq混淆了模拟与代理。如果你想深入理解上述批评观点,必须具备一定的背景知识才行。为此,你不妨参考驱动开发权威Martin Fowler曾写过一篇标题为“Mocks Aren't Stubs”的很有影响的论文,其相关网址为:
http://martinfowler.com/articles/mocksArentStubs.html。

Fowler在上面这篇论文中对好几组概念加以区别。首先,他区别了代理(stub)和模拟(mock)。根据Fowler的看法(此处他引用了Meszaros的定义),代理对于测试期间进行的调用提供了封装现成的答案,经常情况下,这种封装与当前测试之外的内容是毫无关系的。相比之下,模拟(Mocks)是一些提前编写的带有一定期望的对象,这些期望对于所进行的调用加以声明-期望达到的结果。

根据上面这对概念的区别,Fowler又进一步对状态校验(state verification)和行为校验(behavior. verification)加以区别。当执行状态校验时,代理最为常用。当执行状态校验时,你更感兴趣的是测试结束某个条件是真还是假。而另一方面,当执行行为校验时,最为常用的却是模拟(Mocks)。当执行行为校验时,你更感兴趣的是模拟对象之间是如何交互的。例如,你想知道在另一个模拟对象上调用了一个方法之后是否在某个模拟对象上调用了某个特定的方法。

Fowler最后区别了传统的测试驱动开发(classical TDD)和模拟主义测试驱动开发(mockist TDD)。其实,Fowler对这两者的区别涉及到如何进行测试和设计的根本问题。传统的测试驱动开发者趋向于使用代理和状态校验。根据Fowler的说法,传统式测试驱动开发风格在于尽可能使用真正的对象,而当这种情形相当难以实现时又引入近乎两倍的真正对象以试图实现既定测试目的。而一个模拟主义测试驱动开发者几乎总是使用模拟和行为校验方案,他们会一直针对感兴趣的行为使用任何的模拟对象。

一个传统型的测试驱动程序员会使用一个模拟对象框架来简化单元测试。如果你想要测试的代码依赖于另外其他的对象,那么,你可以为当前不太方便的对象快速创建一个代理(stub),从而继续进行你的单元测试工作。因此,从一个传统型的测试驱动程序员角度来看,一个模拟对象框架的主要意义正在于此。

相比之下,模拟主义测试驱动开发者持有完全不同的观点。他们认为,应用程序的设计应该受你期望对象在程序中交互的方式的驱动。因此,他们使用模拟对象来模拟实现最终的应用程序。因此,在测试期间,他们会模拟所有的东西。

Moq因其没有尊重传统型测试驱动开发者和习惯于使用模拟对象进行测试驱动开发的开发者而受到指责。Moq使得很容易地创建代理(stubs)而不是模拟。这或者是一件好事,也可能是一件糟糕的事情,具体要依赖于你使用的模拟对象框架的目标。

Daniel Cazzulino,作为Moq框架的主要创建者,无可辩解地是一位传统型测试驱动开发者。在Daniel Cazzulino和Ayende (Rhino Mocks框架的作者)之间曾经有一次很有意思的意见交流,此网址为:
http://www.ayende.com/Blog/archive/2007/12/19/Moq-Mocking-in-C-3.0.aspx

Daniel Cazzulino认为,大多数的开发者,如果他们使用了测试驱动开发的话,并不会区别什么是传统的测试驱动开发(classical TDD)和什么是模拟主义测试驱动开发(mockist TDD)。事实上,这两者之间的区别并不像Martin Fowler所描述的那样清晰分明。为此,Daniel Cazzulino撰写了一篇论文,题目为“Mocks, Stubs and Fakes: it's a continuum”,其博客地址为:
http://www.clariusconsulting.net/blogs/kzu/archive/2007/12/21/47152.aspx

最终,Daniel Cazzulino没有使用Fowler/Meszaros针对模拟和代理所作出的区别。他呼吁,大多数开发者当引用Fowler/Meszaros所指的“代理”时应该使用“模拟”代之,并且强调大家应当尊重这些词语的日常语言使用习惯。

由于本文后面的内容将介绍Moq的用法,所以,我们也根据Daniel Cazzulino的做法把模拟和代理合并到一起使用。

三、下载和安装Moq

Moq是作为Google代码工程的形式维护的。你可以从网址http://code.google.com/p/moq/处下载Moq的二进制形式及相关API参考文档。

在下载Moq的二进制形式Moq.2.5.3-bin.zip并解压后,你将得到如下图所示的几个文件。


.> .>.>.>.>

注意到,上图中包含了一个程序集Moq.dll。当在Visual Studio中测试你的项目前,你必须添加对于此程序集的引用。当然,你还需要添加对于Moq命名空间的具体引用,以便可以使用其中提供的测试类。

另外请注意:解压结果中还一并提供了一个帮助文件Moq.chm。这是Windows平台上流行的帮助文件格式。通过此文件,你可以详细研究这个模拟对象框架的使用。

 

在接下来的文章中,我将详细介绍.>如何使用Moq创建模拟对象并编写一个简单的实例。
原文地址:http://space.itpub.net/14518332/viewspace-431738.>.>.>.>

.>.>.>.> 

.>.>.>.> 

本文转自温景良(Jason)博客园博客,原文链接:http://www.cnblogs.com/wenjl520/archive/2009/08/21/1551299.html,如需转载请自行联系原作者
.>.>.>.>

相关文章
|
16天前
|
数据可视化 网络协议 C#
C#/.NET/.NET Core优秀项目和框架2024年3月简报
公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。
|
23天前
|
Web App开发 前端开发 Java
《手把手教你》系列技巧篇(九)-java+ selenium自动化测试-元素定位大法之By name(详细教程)
【4月更文挑战第1天】 这篇教程介绍了如何使用Selenium Webdriver通过name属性来定位网页元素,作为系列教程的一部分,之前讲解了id定位,后续还会有其他六种定位方法。文中以百度搜索为例,详细说明了定位搜索框(name=&quot;wd&quot;)并输入关键词“北京宏哥”的步骤,包括手动操作流程、编写自动化脚本以及代码实现。此外,还提供了查看和理解Selenium源码的方法,强调了`open implementation`选项用于查看方法的具体实现。整个过程旨在帮助读者学习Selenium的元素定位,并实践自动化测试。
41 0
|
18天前
|
前端开发 Java 测试技术
《手把手教你》系列技巧篇(十二)-java+ selenium自动化测试-元素定位大法之By link text(详细教程)
【4月更文挑战第4天】本文介绍了link text在自动化测试中的应用。Link text是指网页中链接的文字描述,点击可跳转至其他页面。文章列举了8种常用的定位方法,其中着重讲解了link text定位,并通过实例展示了如何使用Java代码实现点击百度首页的“奥运奖牌榜 最新排名”链接,进入相应页面。如果link text不准确,则无法定位到元素,这说明linkText是精准匹配,而非模糊匹配。文章还提到了partial link text作为link text的模糊匹配版本,将在后续内容中介绍。
37 4
|
17天前
|
XML 前端开发 Java
《手把手教你》系列技巧篇(十四)-java+ selenium自动化测试-元素定位大法之By xpath上卷(详细教程)
【4月更文挑战第6天】按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath。xpath 的定位方法, 非常强大。使用这种方法几乎可以定位到页面上的任意元素。xpath 是XML Path的简称, 由于HTML文档本身就是一个标准的XML页面,所以我们可以使用Xpath 的用法来定位页面元素。XPath 是XML 和Path的缩写,主要用于xml文档中选择文档中节点。基于XML树状文档结构,XPath语言可以用在整棵树中寻找指定的节点。
43 0
|
1天前
|
Web App开发 数据采集 Java
《手把手教你》系列技巧篇(三十)-java+ selenium自动化测试- Actions的相关操作下篇(详解教程)
【4月更文挑战第22天】本文介绍了在测试过程中可能会用到的两个功能:Actions类中的拖拽操作和划取字段操作。拖拽操作包括基本讲解、项目实战、代码设计和参考代码,涉及到鼠标按住元素并将其拖动到另一个元素上或指定位置。划取字段操作则介绍了如何在一段文字中随机选取一部分,包括项目实战、代码设计和参考代码。此外,文章还提到了滑动验证的实现,并提供了相关的代码示例。
11 2
|
5天前
|
Web App开发 JavaScript 前端开发
深入理解自动化测试框架Selenium的设计与实现
【4月更文挑战第20天】 在软件测试领域,自动化测试已成为提升测试效率和确保产品质量的关键手段。Selenium作为一款广泛使用的开源自动化测试框架,其设计精巧且功能强大,为Web应用提供了一种灵活、高效的测试解决方案。本文将深入探讨Selenium的核心架构与实现细节,解析其如何通过模拟用户操作来执行测试用例,以及它如何适应不断变化的Web技术标准。通过对Selenium内部机制的剖析,旨在帮助测试工程师更好地掌握该工具,并在测试实践中发挥其最大效能。
|
6天前
|
前端开发 JavaScript Java
《手把手教你》系列技巧篇(二十五)-java+ selenium自动化测试-FluentWait(详细教程)
【4月更文挑战第17天】其实今天介绍也讲解的也是一种等待的方法,有些童鞋或者小伙伴们会问宏哥,这也是一种等待方法,为什么不在上一篇文章中竹筒倒豆子一股脑的全部说完,反而又在这里单独写了一篇。那是因为这个比较重要,所以宏哥专门为她量身定制了一篇。FluentWait是Selenium中功能强大的一种等待方式,翻译成中文是流畅等待的意思。在介绍FluentWait之前,我们来讨论下为什么需要设置等待,我们前面介绍了隐式等待和显式等待。
29 3
|
7天前
|
监控 测试技术 数据安全/隐私保护
如何将代理IP集成到自动化测试框架中?
如何将代理IP集成到自动化测试框架中?
|
8天前
|
Java 测试技术 定位技术
《手把手教你》系列技巧篇(二十三)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换下卷(详细教程)
【4月更文挑战第15天】本文介绍了如何使用Selenium进行浏览器窗口切换以操作不同页面元素。首先,获取浏览器窗口句柄有两种方法:获取所有窗口句柄的集合和获取当前窗口句柄。然后,通过`switchTo().window()`方法切换到目标窗口句柄。在项目实战部分,给出了一个示例,展示了在百度首页、新闻页面和地图页面之间切换并输入文字的操作。最后,文章还探讨了在某些情况下可能出现的问题,并提供了一个简单的本地HTML页面示例来演示窗口切换的正确操作。
36 0
|
9天前
|
敏捷开发 监控 前端开发
深入理解自动化测试框架Selenium的架构与实践
【4月更文挑战第16天】 在现代软件开发过程中,自动化测试已成为确保产品质量和加快迭代速度的关键手段。Selenium作为一种广泛使用的自动化测试工具,其开源、跨平台的特性使得它成为业界的首选之一。本文旨在剖析Selenium的核心架构,并结合实际案例探讨其在复杂Web应用测试中的高效实践方法。通过详细解读Selenium组件间的交互机制以及如何优化测试脚本,我们希望为读者提供深入理解Selenium并有效运用于日常测试工作的参考。
14 1