JustMock .NET单元测试利器(三)用JustMock测试你的应用程序
用JustMock测试你的应用程序
本主题将指导您通过几个简单的步骤来使用Telerik®JustMock轻松测试您的应用程序。您将理解一个简单的原理,称为Arrange / Act / Assert,并熟悉框架中的核心方法和属性,这些方法和属性在最常见的测试场景中使用
为了说明下一个例子中JustMock的用法,我们将使用一个样本仓库(warehouse)和一个依赖订单对象(Order)。仓库持有不同产品的库存。订单包含产品和数量。
仓库界面和订单类看起来像这样:
publicdelegatevoidProductRemoveEventHandler(string productName,int quantity); publicinterfaceIwarehouse { eventProductRemoveEventHandlerProductRemoved; stringManager{get;set;} boolHasInventory(string productName,int quantity); voidRemove(string productName,int quantity); } publicclassOrder { publicOrder(string productName,int quantity) { this.ProductName= productName; this.Quantity= quantity; } publicstringProductName{get;privateset;} publicintQuantity{get;privateset;} publicboolIsFilled{get;privateset;} publicvoidFill(Iwarehouse warehouse) { if(warehouse.HasInventory(this.ProductName,this.Quantity)) { warehouse.Remove(this.ProductName,this.Quantity); } } publicvirtualstringReceipt(DateTime orderDate) { returnstring.Format("Ordered {0} {1} on{2}",this.Quantity,this.ProductName, orderDate.ToString("d")); } }
方法
DoInstead
DoInstead
当您想要通过用自定义操作替换方法来更改方法的行为时,可以使用该方法。我们用上面的例子来说明如何使用DoInstead
。
[TestMethod] publicvoidDoInstead_TestMethod() { //Arrange var warehouse =Mock.Create<Iwarehouse>(); var order =newOrder("Camera",2); bool called =false; Mock.Arrange(()=> warehouse.HasInventory("Camera",2)).DoInstead(()=> called =true); //Act order.Fill(warehouse); //Assert Assert.IsTrue(called); }
简单的说 -
我们安排,当仓库的HasInventory
方法调用参数“camera”和2,我们将执行行动“ ()=>called=true ”,而不是调用实际的方法。
CallOriginal
在某些情况下,您可能希望在调用原始方法实现时使用特定的值调用该方法,并使用其他值调用模拟。为此,您可以使用该CallOriginal
方法。
[TestMethod] publicvoidCallOriginal_TestMethod() { //Arrange var order =Mock.Create<Order>(Behavior.CallOriginal,"Camera",2); Mock.Arrange(()=> order.Receipt(DateTime.Today)).CallOriginal(); Mock.Arrange(()=> order.Receipt(Arg.Matches<DateTime>(d => d >DateTime.Today))).Returns("InvalidDateTime"); //Act var callWithToday =order.Receipt(DateTime.Today); var callWithDifferentDay = order.Receipt(DateTime.Today.AddDays(1)); //Assert Assert.AreEqual("Ordered 2 Camera on "+DateTime.Today.ToString("d"), callWithToday); Assert.AreEqual("Invalid DateTime", callWithDifferentDay); }
在这个例子中,我们安排当order.Receipt
用参数调用DateTime.Today
方法时,应该调用原来的方法实现。但是,一旦晚于日期调用相同的方法,DateTime.Today
我们将返回“Invalid
DateTime”。
throws
在Throws
当你想抛出一个异常特定方法调用方法时使用。在下面的例子中,我们抛出一个无效的操作异常,试图调用仓库。删除零个数量。
[TestMethod] [ExpectedException(typeof(InvalidOperationException))] publicvoidThrows_TestMethod() { //Arrange var order =newOrder("Camera",0); var warehouse =Mock.Create<Iwarehouse>(); //Set up that the ware house has inventory of any products with any quantities. Mock.Arrange(()=> warehouse.HasInventory(Arg.IsAny<string>(),Arg.IsAny<int>())).Returns(true); //Set up that call to warehouse.Remove with zero quantity is invalid and throwsan exception. Mock.Arrange(()=> warehouse.Remove(Arg.IsAny<string>(),Arg.Matches<int>(x => x ==0))) .Throws(newInvalidOperationException()); //Act order.Fill(warehouse); }
在这种情况下,我们使用ExpectedException
属性Microsoft.VisualStudio.TestTools.UnitTesting
来验证类型InvalidOperationException
的异常是否被抛出。
Machers
匹配器让你忽略传递实际值作为模拟中使用的参数。相反,它们给你传递一个满足参数类型或期望值范围的表达式的可能性。例如,如果方法接受字符串作为第一个参数,则不需要传递特定的字符串,如“Camera”,而是可以使用Arg.IsAny<string>()
。
JustMock支持三种类型的匹配器:
1. Arg.IsAny<[Type]>();
2. Arg.IsInRange([FromValue : int], [ToValue : int],[RangeKind])
3. Arg.Matches(Expression> expression)
我们来看看它们的详细用法。
Arg.IsAny();
我们已经在上面的一个例子中使用了这个匹配器。
Mock.Arrange(()=> warehouse.HasInventory(Arg.IsAny<string>(),Arg.IsAny<int>())).Returns(true);
这个匹配器指定当HasInventory
任何字符串作为第一个参数调用方法,任何int作为第二个参数时,它应该返回true
。
Arg.IsInRange(int
from,int to,RangeKind range)
IsInRange匹配器让我们安排一个预期值范围的调用。通过RangeKind
论证,我们可以指定给定的范围是包含还是排除其边界。
对于范围从到的参数值,将返回以下内容true
:
Mock.Arrange(()=> foo.Echo(Arg.IsInRange(0,5,RangeKind.Inclusive))).Returns(true);
Arg.Matches (Expression>
expression)
这是最灵活的匹配器,它允许你指定你自己的匹配表达式。我们用一个简单的例子来说明:
Mock.Arrange(()=> foo.Echo(Arg.Matches<int>( x => x <10)).Returns(true);
属性
在上面的例子中,我们只模拟方法,但是你也可以用同样的方法来模拟属性。
[TestMethod] publicvoidMockingProperties_TestMethod() { //Arrange var warehouse =Mock.Create<Iwarehouse>(); Mock.Arrange(()=> warehouse.Manager).Returns("John"); string manager =string.Empty; //Act manager = warehouse.Manager; //Assert Assert.AreEqual("John", manager); }
另外,还可以给属性赋值
[TestMethod] [ExpectedException(typeof(StrictMockException))] publicvoidMockingProperties_PropertySet_TestMethod() { //Arrange var warehouse =Mock.Create<Iwarehouse>(Behavior.Strict); Mock.ArrangeSet(()=> warehouse.Manager="John"); //Act warehouse.Manager="Scott"; }
在安排步骤中,我们设置仓库经理只能设置为“John”。但是在行动步骤中,我们将经理设置为“Scott”。这抛出了一个模拟异常。请记住,这只会在您使用StrictBehavior创建模拟时才起作用。
另一个常用的技巧是断言将属性设置为特定值会引发异常。我们来安排一下
[TestMethod] [ExpectedException(typeof(ArgumentException))] publicvoidMockingProperties_PropertySet_Throws_TestMethod() { //Arrange var warehouse =Mock.Create<Iwarehouse>(); Mock.ArrangeSet(()=> warehouse.Manager="John").Throws<ArgumentException>(); //Act //that's ok warehouse.Manager="Scott"; //but that would throw an ArgumentException warehouse.Manager="John"; }
在这里,我们使用Throws
上面讨论的方法来表明如果warehouse.Manager
设置为“John”,则应抛出异常。
活动
该方法Raises
允许您在调用方法时引发事件并传递特定的事件参数。回到我们的仓库示例,我们可能想要在调用ProductRemoved
该Remove
方法时引发事件。
[TestMethod] publicvoidRaisingAnEvent_TestMethod() { //Arrange var warehouse =Mock.Create<Iwarehouse>(); Mock.Arrange(()=> warehouse.Remove(Arg.IsAny<string>(),Arg.IsInRange(int.MinValue,int.MaxValue,RangeKind.Exclusive))) .Raises(()=> warehouse.ProductRemoved+=null,"Camera",2); string productName =string.Empty; int quantity =0; warehouse.ProductRemoved+=(p, q)=>{ productName = p; quantity =q;}; //Act warehouse.Remove(Arg.AnyString,Arg.AnyInt); //Assert Assert.AreEqual("Camera", productName); Assert.AreEqual(2, quantity); }
在安排步骤中,我们设置一旦仓库的Remove
方法被调用,我们将ProductRemoved
用参数“Camera”和2 来提升调用事件。
项目GitHub地址:https://github.com/liuzhenyulive/JustMockDemo
参考文献:http://docs.telerik.com/devtools/justmock/getting-started/quick-start#testing-your-application-with-justmock
JustMock .NET单元测试利器(三)用JustMock测试你的应用程序的更多相关文章
- JustMock .NET单元测试利器(一)
1.什么是Mock? Mock一词是指模仿或者效仿,用于创建实例和静态模拟.安排和验证行为.在软件开发中提及"mock",通常理解为模拟对象.模拟对象的概念就是我们想要创建一个可以 ...
- JustMock .NET单元测试利器(二)JustMock基础
JustMock API基础 Mock是Telerik®JustMock框架中的主要类.Mock用于创建实例和静态模拟,安排和验证行为. 本文将介绍 "Mock"的基本用法: 首先 ...
- 单元测试利器 JUnit 4
引言 毋庸置疑,程序员要对自己编写的代码负责,您不仅要保证它能通过编译,正常地运行,而且要满足需求和设计预期的效果.单元测试正是验证代码行为是否满足预期的有效手段之一.但不可否认,做测试是件很枯燥无趣 ...
- [转]单元测试利器 JUnit 4
引言 毋庸置疑,程序员要对自己编写的代码负责,您不仅要保证它能通过编译,正常地运行,而且要满足需求和设计预期的效果.单元测试正是验证代码行为是否满足预期的有效手段之一.但不可否认,做测试是件很枯燥无趣 ...
- PHP单元测试利器:PHPUNIT初探
开始动手安装phpunit 本文中将通过介绍php中的单元测试利器phpunit(http://phpunit.de/),并通过实际例子来讲解如何在实际工作中运用phpunit.首先安装phpunit ...
- 【Linux探索之旅】第一部分第三课:测试并安装Ubuntu
内容简介 1.第一部分第三课:测试并安装Ubuntu 2.第一部分第四课预告:磁盘分区 测试并安装Ubuntu 大家好,经过前两个比较偏理论(是否想起了带着瓜皮帽,手拿折扇的老学究,或者腐儒)的课程, ...
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(三)代码测试
日常啰嗦 看到标题你可能会问为什么这一篇会谈到代码测试,不是说代码优化么?前两篇主要是讲了程序的输出及Log4j的使用,Log能够帮助我们进行bug的定位,优化开发流程,而代码测试有什么用呢?其实测试 ...
- Android单元测试之四:仪器化测试
Android单元测试之四:仪器化测试 仪器化测试 在某些情况下,虽然可以通过模拟的手段来隔离 Android 依赖,但代价很大,这种情况下可以考虑仪器化的单元测试,有助于减少编写和维护模拟代码所需的 ...
- 20175316盛茂淞 《java程序设计》第三周课堂测试错题总结
20175316盛茂淞 <java程序设计>第三周课堂测试错题总结 出现问题 错题总结 题目1 在Ubuntu中用自己的有位学号建一个文件,教材p87 Example4_15 1. 修改代 ...
随机推荐
- BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]
有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...
- 【视频编解码·学习笔记】6. H.264码流分析工程创建
一.准备工作: 新建一个VS工程SimpleH264Analyzer, 修改工程属性参数-> 输出目录:$(SolutionDir)bin\$(Configuration)\,工作目录:$(So ...
- Linux设置系统运行模式
Linux系统有7个运行级别(runlevel): 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆 运行级 ...
- 用 k8s 运行一次性任务 - 每天5分钟玩转 Docker 容器技术(132)
容器按照持续运行的时间可分为两类:服务类容器和工作类容器. 服务类容器通常持续提供服务,需要一直运行,比如 http server,daemon 等.工作类容器则是一次性任务,比如批处理程序,完成后容 ...
- Node.js爬取豆瓣数据
一直自以为自己vue还可以,一直自以为webpack还可以,今天在慕课逛node的时候,才发现,自己还差的很远.众所周知,vue-cli基于webpack,而webpack基于node,对node不了 ...
- LearnPython_week1
1. Python安装 2. Hello World程序 3. 变量的简单使用 4. 注释#'" 5. 用户输入 6. 字符串格式 ...
- 配置可以通过http协议访问的svn服务器
通过HTTP协议访问版本库是Subversion的亮点之一,这种方式具备许多svnserve服务器所没有的特性,使用上更加灵活. 关于mode_day_svn模块: 由于Subversion需要版本化 ...
- appium+Python 启动app(三)登录
我们根据前面的知识点,用uiautomatorviewer工具来获取我们当前的元素 (注:uiautomatorviewer 是 android sdk 自带的) 知识点:appium的webdriv ...
- 基于Java SE集合的充值管理系统
1.功能分析 ①管理员管理 注册.登录.退出 ②注册一卡通:记录相应信息. ③充值管理:对一卡通账户进行充值,查询,修改. 2.技术要求 ①Java 基础知识 + 集合类(模拟数据库). ②数据用对象 ...
- 【记录】.net 通用log4net日志配置
asp.net mvc 1.引入log4netNuGet包. 2.修改Global.asax下的Application_Start方法.加入log4net.Config.XmlConfigurator ...