在.net中有几种mock框架可供选择,比如NMock,PhinoMocks,FakeItEasy和Moq。尽管Moq相对较新,但是它非常易用。不需要像传统的Record/Replay。并且使用Moq在VS中可以得到智能提示。学习成本也不高。

这篇文章我们介绍下如何使用Moq来mock吧。

假定我们要做一个计算器提供基本的算术运算和不同货币的转换。

ICaculator接口定义如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace CalculatorPkg
  7. {
  8. public interface ICalculator
  9. {
  10. int Add(int param1, int param2);
  11. int Subtract(int param1, int param2);
  12. int Multipy(int param1, int param2);
  13. int Divide(int param1, int param2);
  14. int ConvertUSDtoRMB(int unit);
  15. }
  16. }

假定人民币转美元的接口定义如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace MoneyExchangeRatePkg
  7. {
  8. public interface IUSD_RMB_ExchangeRateFeed
  9. {
  10. int GetActualUSDValue();
  11. }
  12. }

下面是Calculator的实现类,其中人民币转美元的接口实例以构造函数参数的形式传给Calculator类。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using MoneyExchangeRatePkg;
  6.  
  7. namespace CalculatorPkg
  8. {
  9. public class Calculator : ICalculator
  10. {
  11. private IUSD_RMB_ExchangeRateFeed _feed;
  12. public Calculator(IUSD_RMB_ExchangeRateFeed feed)
  13. {
  14. this._feed = feed;
  15. }
  16. #region ICalculator Members
  17. public int Add(int param1, int param2)
  18. {
  19. throw new NotImplementedException();
  20. }
  21. public int Subtract(int param1, int param2)
  22. {
  23. throw new NotImplementedException();
  24. }
  25. public int Multipy(int param1, int param2)
  26. {
  27. throw new NotImplementedException();
  28. }
  29. public int Divide(int param1, int param2)
  30. {
  31. return param1 / param2;
  32. }
  33. public int ConvertUSDtoRMB(int unit)
  34. {
  35. return unit * this._feed.GetActualUSDValue();
  36. }
  37. #endregion
  38. }
  39. }

下面我们开始准备Calculator组件的测试环境,我们使用NUnit框架和Moq来做Mock。

您可以到http://www.nunit.org/获得nunit,到http://code.google.com/p/moq/获得moq框架的源码和dll文件。

然后我们就可以创建测试项目,并添加nunit和moq的引用。

我们要mock汇率的接口,下面是mock的方法:

  1. Mock<IUSD_RMB_ExchangeRateFeed> mockObject = new Mock<IUSD_RMB_ExchangeRateFeed>();
  2. mockObject.Setup(m => m.GetActualUSDValue()).Returns(500);
  3. IUSD_RMB_ExchangeRateFeed value = mockObject.Object;

对汇率接口的MOCK只需要三行代码,第一行声明mock接口,第二行设定要mock方法的返回值,第三步通过Object属性获得mock的对象。

下面是完整的测试代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using NUnit.Framework;
  6. using Moq;
  7. using CalculatorPkg;
  8. using MoneyExchangeRatePkg;
  9.  
  10. namespace CalculatorPkg.Tests
  11. {
  12. // 添加TestFixture标识类是测试类
  13. [TestFixture]
  14. public class CalculatorTester
  15. {
  16. // 定义mock的逻辑
  17. private IUSD_RMB_ExchangeRateFeed prvGetMockExchangeRateFeed()
  18. {
  19. Mock<IUSD_RMB_ExchangeRateFeed> mockObject = new Mock<IUSD_RMB_ExchangeRateFeed>();
  20. mockObject.Setup(m => m.GetActualUSDValue()).Returns(500);
  21. return mockObject.Object;
  22. }
  23. // 测试divide方法
  24. [Test(Description="Divide 9 by 3. Expected result is 3.")]
  25. public void TC1_Divide9By3()
  26. {
  27. IUSD_RMB_ExchangeRateFeed feed = this.prvGetMockExchangeRateFeed();
  28. ICalculator calculator = new Calculator(feed);
  29. int actualResult = calculator.Divide(9,3);
  30. int expectedResult = 3;
  31. Assert.AreEqual(expectedResult, actualResult);
  32. }
  33. [Test(Description = "Divide any number by zero. Should throw an System.DivideByZeroException exception.")]
  34. [ExpectedException(typeof(System.DivideByZeroException))]
  35. public void TC2_DivideByZero()
  36. {
  37. IUSD_RMB_ExchangeRateFeed feed = this.prvGetMockExchangeRateFeed();
  38. ICalculator calculator = new Calculator(feed);
  39. int actualResult = calculator.Divide(9, 0);
  40. }
  41. [Test(Description = "Convert 1 USD to RMB. Expected result is 500.")]
  42. public void TC3_ConvertUSDtoRMBTest()
  43. {
  44. IUSD_RMB_ExchangeRateFeed feed = this.prvGetMockExchangeRateFeed();
  45. ICalculator calculator = new Calculator(feed);
  46. int actualResult = calculator.ConvertUSDtoRMB(1);
  47. int expectedResult = 500;
  48. Assert.AreEqual(expectedResult, actualResult);
  49. }
  50. }
  51. }
 

c#单元测试:使用Moq框架Mock对象的更多相关文章

  1. 基于spring与mockito单元测试Mock对象注入

    转载:http://www.blogjava.net/qileilove/archive/2014/03/07/410713.html 1.关键词 单元测试.spring.mockito 2.概述 单 ...

  2. 单元测试与Moq

    这个篇幅里面,记录单元测试与Moq模拟包的知识点. 单元测试 每一个模块,都应该有对应的单元测试.单元测试可以保证你的代码准确性,大大减少出现BUG的几率.一个好的单元测试,也是重构代码必不可少的部分 ...

  3. .net测试篇之Moq框架简单使用

    系列目录 Moq库简介及安装 Moq简介 Moq是.net平台下的一个非常流行的模拟库,只要有一个接口它就可以动态生成一个对象,底层使用的是Castle的动态代理功能. 它的流行赖于依赖注入模式的兴起 ...

  4. 简单使用Moq框架

    Moq框架简单使用   系列目录 Moq库简介及安装 Moq简介 Moq是.net平台下的一个非常流行的模拟库,只要有一个接口它就可以动态生成一个对象,底层使用的是Castle的动态代理功能. 它的流 ...

  5. 单元测试利器Mockito框架

    什么是Mock Mock 的中文译为仿制的,模拟的,虚假的.对于测试框架来说,即构造出一个模拟/虚假的对象,使我们的测试能顺利进行下去. Mock 测试就是在测试过程中,对于某些 不容易构造(如 Ht ...

  6. 单元测试系列之五:Mock工具之Mockito实战

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6780719.html 在实际项目中写单 ...

  7. 在SpringTest中将Mockito的mock对象通过spring注入使用

    转载:https://blog.csdn.net/m0_38043362/article/details/80111957 1. 原理介绍 通过BeanFactoryPostProcessor向Bea ...

  8. 持续集成之路 —— Mock对象引起的测试失败

    今天遇到了一个很奇怪的问题,纠结了好久.在和同事念叨这个问题时,突然想到了问题所在. 问题现象: 在一个Service的单元测试类中有八个测试用例,单独运行时都可以正常通过.可是一旦一起运行时,总是会 ...

  9. python学习笔记(十五)-unittest单元测试的一个框架

    unittest 单元测试的一个框架什么框架 一堆工具的集合. TestCase TestSuite 测试套件,多个用例在一起 TestLoader是用来加载TestCase到TestSuite中的 ...

随机推荐

  1. Jenkins构建次数设置

    Build after other projects are built:在其他项目触发的时候触发,里面有分为三种情况,也就是其他项目构建成功.失败.或者不稳定的时候触发项目: Poll SCM:定时 ...

  2. oracle进阶之connect by笔记

    本博客是自己在学习和工作途中的积累与总结,仅供自己参考,也欢迎大家转载,转载时请注明出处. http://www.cnblogs.com/king-xg/p/6794562.html 如果觉得对您有帮 ...

  3. js常用函数整理

    类型转换:parseInt\parseFloat\toString 类型判断:typeof;eg:if(typeof(var)!="undefined")\isNaN 字符处理函数 ...

  4. Python 正则表达式模块 (re) 简介

    Python 的 re 模块(Regular Expression 正则表达式)提供各种正则表达式的匹配操作,和 Perl 脚本的正则表达式功能类似,使用这一内嵌于 Python 的语言工具,尽管不能 ...

  5. lnmp创建站点

    一.创建站点 1.输入命令 lnmp vhost add 输入域名 www.xxx.com 回车 回车 回车 y创建 n不创建 网站如果有目录权限 更改目录权限 chown -R www:www /h ...

  6. ZOJ 3229 Shoot the Bullet(有源汇上下界最大流)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 题目大意: 一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝给 ...

  7. python 全栈开发,Day27(复习, defaultdict,Counter,时间模块,random模块,sys模块)

    一.复习 看下面一段代码,假如运行结果有问题,那么就需要在每一步计算时,打印一下结果 b = 1 c = 2 d = 3 a = b+c print(a) e = a + d print(e) 执行输 ...

  8. 如何获取JMX监控WebSphere所需的com.ibm.ws.admin.client_8.5.0等jar包

    https://blog.csdn.net/weixin_38645718/article/details/83346007

  9. mongo 复制集命令

    1.登录primary2.use admin >rs.add("new_node:port") 或 rs.add({"_id":4,"host& ...

  10. Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架

    Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...