在.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);
}
}
}
 

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. Eclipse开发时出现HTTP 403 错误(禁止访问)的解决方法

    1. 打开项目的页面如下: 可以从tomcat log中发现Connection has been abandoned PooledConnection和Too many connections. 2 ...

  2. asp.net core 2.0 api ajax跨域问题

    API配置: services.AddCors(options => { options.AddPolicy("any", builder => { builder.W ...

  3. main.js 里的/* eslint-disable no-new */

    注意项目中的这个,它的作用是: 在js里面,new 一个对象,需要赋值给某个值(变量),用Vue实例化的时候,不需要赋值给值(变量),所以要单独给配一条规则,给new Vue这行代码上面加这个注释,把 ...

  4. PHP对Url中的汉字进行编码和解码

    有的新手朋友们对于url编码解码这个概念,或许有点陌生.但是如果这么说,当我们在浏览各大网页时,可能发现有的url里有一些特殊符号比如#号,&号,_号或者汉字等等,那么为了符合url的规范,存 ...

  5. poj1742 多维背包

    普通的多维背包做不了,需要优化一下 但是没有学优化..别的方法也是可以做的 省去一个 表示阶段的 i 维度,dp[j]表示面值为j的钱是否被凑出来了,used[j]表示第i种硬币在凑面值为j的时候被用 ...

  6. 步步为营-47-分页显示的SQL语句

    说明:分页显示在实际业务中经常需要用到,其SQL语句分两种 1:分页显示SQL语句 --方法一:跳过多少行,选中多少行 --每页n条,选择第m页--n= m= --)*n 主键 from 表); se ...

  7. 《剑指offer》-表示数值的字符串

    请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.1416&q ...

  8. DDD模型领域WF到领域层(十五)

    实现超市的结算系统: 计算相应的优惠方式的接口 public interface ICompute { double GetResultTotalMoney(double TotalMoney); } ...

  9. day1作业--登录接口

    作业:编写登陆接口 输入用户名密码 认证成功后显示欢迎信息 输错三次后锁定     知识: 1.循环的使用: 2.continue,break在循环中中断的作用: 3.文件的写入,读取: 4.各基础知 ...

  10. floor()函数 和round()函数的区别

    floor()函数 和round()函数的区别 2018-08-17  09:40:00 1.floor()函数:取整,保留整数部分,舍弃小数部分. 2.round()函数:四舍五入.round(x, ...