c#单元测试:使用Moq框架Mock对象
在.net中有几种mock框架可供选择,比如NMock,PhinoMocks,FakeItEasy和Moq。尽管Moq相对较新,但是它非常易用。不需要像传统的Record/Replay。并且使用Moq在VS中可以得到智能提示。学习成本也不高。
这篇文章我们介绍下如何使用Moq来mock吧。
假定我们要做一个计算器提供基本的算术运算和不同货币的转换。
ICaculator接口定义如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CalculatorPkg { public interface ICalculator { int Add(int param1, int param2); int Subtract(int param1, int param2); int Multipy(int param1, int param2); int Divide(int param1, int param2); int ConvertUSDtoRMB(int unit); } }
假定人民币转美元的接口定义如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MoneyExchangeRatePkg { public interface IUSD_RMB_ExchangeRateFeed { int GetActualUSDValue(); } }
下面是Calculator的实现类,其中人民币转美元的接口实例以构造函数参数的形式传给Calculator类。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using MoneyExchangeRatePkg; namespace CalculatorPkg { public class Calculator : ICalculator { private IUSD_RMB_ExchangeRateFeed _feed; public Calculator(IUSD_RMB_ExchangeRateFeed feed) { this._feed = feed; } #region ICalculator Members public int Add(int param1, int param2) { throw new NotImplementedException(); } public int Subtract(int param1, int param2) { throw new NotImplementedException(); } public int Multipy(int param1, int param2) { throw new NotImplementedException(); } public int Divide(int param1, int param2) { return param1 / param2; } public int ConvertUSDtoRMB(int unit) { return unit * this._feed.GetActualUSDValue(); } #endregion } }
下面我们开始准备Calculator组件的测试环境,我们使用NUnit框架和Moq来做Mock。
您可以到http://www.nunit.org/获得nunit,到http://code.google.com/p/moq/获得moq框架的源码和dll文件。
然后我们就可以创建测试项目,并添加nunit和moq的引用。
我们要mock汇率的接口,下面是mock的方法:
Mock<IUSD_RMB_ExchangeRateFeed> mockObject = new Mock<IUSD_RMB_ExchangeRateFeed>(); mockObject.Setup(m => m.GetActualUSDValue()).Returns(500); IUSD_RMB_ExchangeRateFeed value = mockObject.Object;
对汇率接口的MOCK只需要三行代码,第一行声明mock接口,第二行设定要mock方法的返回值,第三步通过Object属性获得mock的对象。
下面是完整的测试代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; using Moq; using CalculatorPkg; using MoneyExchangeRatePkg; namespace CalculatorPkg.Tests { // 添加TestFixture标识类是测试类 [TestFixture] public class CalculatorTester { // 定义mock的逻辑 private IUSD_RMB_ExchangeRateFeed prvGetMockExchangeRateFeed() { Mock<IUSD_RMB_ExchangeRateFeed> mockObject = new Mock<IUSD_RMB_ExchangeRateFeed>(); mockObject.Setup(m => m.GetActualUSDValue()).Returns(500); return mockObject.Object; } // 测试divide方法 [Test(Description="Divide 9 by 3. Expected result is 3.")] public void TC1_Divide9By3() { IUSD_RMB_ExchangeRateFeed feed = this.prvGetMockExchangeRateFeed(); ICalculator calculator = new Calculator(feed); int actualResult = calculator.Divide(9,3); int expectedResult = 3; Assert.AreEqual(expectedResult, actualResult); } [Test(Description = "Divide any number by zero. Should throw an System.DivideByZeroException exception.")] [ExpectedException(typeof(System.DivideByZeroException))] public void TC2_DivideByZero() { IUSD_RMB_ExchangeRateFeed feed = this.prvGetMockExchangeRateFeed(); ICalculator calculator = new Calculator(feed); int actualResult = calculator.Divide(9, 0); } [Test(Description = "Convert 1 USD to RMB. Expected result is 500.")] public void TC3_ConvertUSDtoRMBTest() { IUSD_RMB_ExchangeRateFeed feed = this.prvGetMockExchangeRateFeed(); ICalculator calculator = new Calculator(feed); int actualResult = calculator.ConvertUSDtoRMB(1); int expectedResult = 500; Assert.AreEqual(expectedResult, actualResult); } } }
个人主要研究:金融系统、MIS系统、人力资源管理系统、数据采集系统、权限管理系统等等系统。主攻C#开发语言,Oracle、Sql Server,WCF和Remoting通信。
如需联系可加QQ:442389681 Email:lxc880615@163.com 手机:18922735098
QQ群交流:186841119 (请注明来自博客园)
博客园地址:http://www.cnblogs.com/jara/ http://www.cnblogs.com/luoyuhao/
提示:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。
如果对文章有任何问题,都可以在评论中留言,我会尽可能的答复您,谢谢您的阅读
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库