在之前的例子中,我们创建了FakeRepository类来支持我们的测试。但是我们还没有解释如何穿件一个真实的repository实现,我们需要一个替代品。一旦我们有一个真的实现,我们可能不会再用它,因为它把我们的测试环境变得复杂。

FakeRepository类,是IProductRepository接口的伪实现。我们创建伪实现,并手动添加特别的参数,使得FakeRepository类手动的仿制品。Moq是一个框架,让我们仿制变得快速,简单,容易。

1 将Moq添加到测试项目,而不是应用程序项目

2 使用Moq创建一个Mock

使用mocking工具的好处是,我们能创建一个为满足测试中的功能定制的Mocks。这意味着我们最终不会得到太复杂的mock实现。在一个真实的项目中,不像这些简单的例子。我们能容易地抵达舞台,mock实例需要它自己的测试,因为它包含足够的代码。我们能手工创建一些mock,为了使它们生效,我们需要移动循环代码到基类,我们正确的返回会变得更复杂。有两个舞台需要使用Moq创建mock,第一个创建一个新的Mock<T>,这个T是我们想要mock的。

第二个舞台是配置实现要展示的行为。Moq会自动实现我们在类型中给它的所有的方法和属性,它会使用类型的默认值。例如,IProductRepository.GetProducts方法会返回一个空的IEnumerable<Product>。要改变Moq实现一个类型成员的方法,我们需要使用Setup方法。

3 使用Moq方法选择器

第一个参数是被选择的方法。Moq使用Linq和Lambda表达式。当我们调用Setup方法,Moq传递接口。当我们想要为GetProducts方法定义一个行为,我们可以这样做

1 mock.Setup(m => m.GetProducts()).(<...other methods...>);

我们不需要知道它内部是怎样工作的,只需要照着做就行了。GetProduct方法容易处理,是因为它没有参数。如果我们想要处理携带参数的方法,我们需要考虑第二个元素:参数过滤。

4 使用Moq的参数渗透

1 publicinterface IMyInterface { 2 string ProcessMessage(string message); 3 } 4 5 Mock<IMyInterface> mock =new Mock<IMyInterface>(); 6 mock.Setup(m => m.ProcessMessage("hello")).Returns("Hi there"); 7 mock.Setup(m => m.ProcessMessage("bye")).Returns("See you soon");

要为所有可能的参数设置相应,可以使用Moq提供的It类。

1 mock.Setup(m => m.ProcessMessage(It.IsAny<string>())).Returns("Message received");

It类定义一些方法,配合一般型参数使用。我们调用IsAny方法,使用string作为一般类型。这告诉Moq,当ProcessMessage方法伴着任何string值被调用,它会返回相应Message Recived。

Method Description
Is<T>() 匹配基于指定的条件
IsAny<T>() 当参数是任何T类型的实例时匹配
IsInRange<T> 当参数在指定值之间时匹配
IsRegex 当匹配指定的正则表达式时匹配

Is<T>方法时最灵活的,因为它让我们提供一个条件。

1 mock.Setup(m => m.ProcessMessage(It.Is<string>(s => s =="hello"|| s =="bye"))) 2 .Returns("Message received");

当string参数是hello或bye时,返回Message Recived。

5 返回一个结果

当我们配置行为时,我们也定义它被触发时的返回方法。上个例子中,Returns方法链式地Setup方法。我们也可以使用传递给mocked方法的参数,给Return方法,让output基于input。

1 mock.Setup(m => m.ProcessMessage(It.IsAny<string>())) 2 .Returns<string>(s =>string.Format("Message received: {0}", s));

6 使用Moq的单元测试

一旦配置好必须的行为,你可以通过Mock.Object属性得到mocked的实现。

1 [TestClass()] 2 publicclass MyPriceReducerTest 3 { 4 private IEnumerable<Product> products; 5 6 [TestInitialize] 7 publicvoid PreTestInitialize() 8 { 9 products =new Product[] 10 { 11 new Product(){Name="Kayak",Price=275M}, 12 new Product(){Name="Lifejacket",Price=48.95M}, 13 new Product(){Name="Soccer ball",Price=19.50M}, 14 new Product(){Name="Stadium",Price=79500M} 15 }; 16 }

为所有测试准备公共数据。单元测试的属性:

Attribute Description
ClassInitialize 在类中的单元测试被执行之前调用。必须应用给静态方法
ClassCleanup 在类中的所有方法执行完成后调用。必须应用给静态方法
TestInitialize 在每个测试执行前调用
TestCleanup 在每个测试执行后调用

VS只看这些属性,方法的名字不重要。

7 使用Moq验证

当每个Product对象被处理时,UpdateProduct方法会被调用。在FakeRepository类中,我们我们定义了一个自增的属性。我们能用Moq以更优美的方式实现相同的效果。

1 //Assert2 foreach (Product p in products) 3 { 4 mock.Verify(m => m.UpdateProduct(p), Times.Once()); 5 }

使用参数渗透,我们能验证UpdateProduct方法,恰好被每个Product对象调用一次。

转载于:https://www.cnblogs.com/msdynax/p/3281913.html

【Pro ASP.NET MVC 3 Framework】.学习笔记.4.MVC的主要工具-使用Moq相关推荐

  1. ASP.NET MVC 3 Framework 学习笔记

    前段时间因项目需要对ASP.NET MVC3进行了系统的学习,完成项目后感觉对原书中有些知识点还有一些理解不够透彻的地方,因此将<Freeman A. Sanderson S. -  Pro A ...

  2. ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步

    http://blog.jobbole.com/85008/ ASP.Net MVC开发基础学习笔记(5):区域.模板页与WebAPI初步 2015/03/17 · IT技术 · .Net, Asp. ...

  3. ASP.NET Core 3.x 学习笔记(7)——Blazor

    ASP.NET Core 3.x 学习笔记(7)--Blazor ASP.NET Core 3.x 学习笔记(7)--Blazor 编程模式对比 Blazor 客户端宿主模型 Mono 服务器端宿主模 ...

  4. 用ajax做级联操作,学习笔记之MVC级联及Ajax操作

    由于刚转型到MVC,MVC的架构模式很多不是很清楚,比如今天就想做个级联的操作,因为之前的ASP.NET的方式是通过:控件-->添加事件-->后台编写级联事件进行触发,但是这个MVC就不同 ...

  5. MVC缓存OutPutCache学习笔记 (一) 参数配置

    OutPutCache 参数详解 Duration : 缓存时间,以秒为单位,这个除非你的Location=None,可以不添加此属性,其余时候都是必须的. Location : 缓存放置的位置; 该 ...

  6. php mvc 路由,PHP MVC框架路由学习笔记

    文章主要介绍了PHP MVC框架路由学习笔记的相关资料,需要的朋友可以参考下. 提到PHP开发web,自然离不开开发框架,开发框架为我们提供了灵活的开发方式,MVC层分离,业务解耦等... 第一篇先来 ...

  7. 从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---11. MVC功能之http请求处理器的编写---简易框架最后一公里!

    从零写一个具有IOC-AOP-MVC功能的框架-学习笔记 专栏往期文章链接: IOC功能相关章节: 从零写一个具有IOC-AOP-MVC功能的框架-学习笔记-01.项目初始化 从零写一个具有IOC-A ...

  8. 《Go语言圣经》学习笔记 第十章 包和工具

    <Go语言圣经>学习笔记 第十章 包和工具 目录 包简介 导入路径 包声明 导入声明 包的匿名导入 包和命名 工具 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. G ...

  9. gnu make 手册 学习笔记 C语言 / C++ 构建工具 part.5 函数 控制语句

    GNU Make manual 学习笔记 C语言 / c++ 构建工具 5.函数,控制语句 5-1.函数 5-1-1.替换,函数$(subst from,to,text), 5-1-2.替换,函数$( ...

  10. ASP.Net MVC开发基础学习笔记(1):走向MVC模式

    原文出处: Edison Chou的博客(@周旭龙EdisonChou)    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebFor ...

最新文章

  1. php怎么四舍五入,php 四舍五入的三种实现方法
  2. 【ArcGIS风暴】ArcGIS获取一个省各个地区界内的河流的总长度--以甘肃省为例
  3. linux磁盘写保护怎么修改_mount: /dev/vdb 写保护,将以只读方式挂载
  4. 关于Java中对于jsp文件的浅认识
  5. Pseudo code:伪代码
  6. 阿里开发规范_字字珠玑,高级技术专家带你了解阿里的开发流程规范
  7. 物联网全面崛起 LED企业大有可为
  8. Spring Boot/Cloud 背后豪华的研发团队
  9. python shell常用命令_python 之 shell命令执行
  10. sql语句中用select语句查询值大于平均值的情况
  11. radio单选框操作
  12. HTML期末作业-我的大学宿舍
  13. 启动界面、封面图片、Splash关不掉,一直转圈,无法进入
  14. 【React】React三大属性:Props、State、Refs
  15. 27. 尚融宝申请借款额度
  16. 作业:会员制营销| Email营销(山姆公司培训方案)
  17. 天津租用网站的服务器,天津怎么租服务器
  18. 设计模式 - 享元 代理
  19. COCO2014 数据集内容解析(含ubuntu下载)
  20. java-net-php-python-ssm办公用品采购平台(2)计算机毕业设计程序

热门文章

  1. php 慢日志,php-fpm慢执行日志
  2. 2016计算机二级考试c语言真题及答案,计算机二级考试c语言真题_2017计算机二级考试C语言复习题及答案...
  3. Botanical Dimensions:借助第九代智能英特尔® 酷睿™ 处理器实现独特沉浸式体验...
  4. Struts(十二):异常处理:exception-mapping元素
  5. 通过管理门户部署云服务与VIP交换
  6. hadoop集群安装配置
  7. C++20 模式下将启用协程支持 CC 11
  8. 2016 年最值得程序员阅读的开源书:《全栈增长工程师指南》
  9. Android ConnectivityManager详解
  10. 黑马程序员C++学习笔记(第一阶段:基础)