我们在做单元测试的时候,常常困扰于数据的持久化问题,很多情况下我们不希望单元测试影响到数据库中的内容,而且受数据库的影响有时我们的单元测试的速度会很慢,所以我们往往希望将持久化部分隔离开,做单元测试的时候不真正的将数据持久化。这种隔离我们一般使用抽象的方式,也就是利用接口或抽象类将持久化层隔离开,然后利用mock来模拟相应的接口或抽象类来完成相应的持久化类。MoQ就是这种Mock框架之一,MoQ使用了C#3.0,跟NMock相比MoQ使用起来更简单,而且是强类型的方式的,源码和dll可以到http://code.google.com/p/moq/下载。现在MoQ最新的发布版本是3.1版,4.0还处在beta版中,所以我们这里使用的是3.1版。

下面我们就来介绍一下MoQ的具体用法:

一、基础知识

在使用MoQ之前我们必须要先在测试程序中引入Moq.dll,使用MoQ的主要命名空间是Moq,其中最重的类就是Mock<T>,我们可以用这个类来模拟接口。

1、方法

   public interface ITest
    {
        string Test();
    }

测试代码:

1      [TestMethod()]
2         public void TestTest()
3         {
4             var test = new Mock<ITest>();
5             test.Setup(p => p.Test()).Returns("lfm");
6             Assert.AreEqual("lfm", test.Object.Test());
7         }

2、匹配参数

 public interface IMatchTest
    {
        string Test(int test);
    }
var testMatch = new Mock<IMatchTest>();
            testMatch.Setup(p => p.Test(It.Is<int>(i => i % 2 == 0))).Returns("偶数");
            testMatch.Setup(p => p.Test(It.Is<int>(i => i % 2 != 0))).Returns("奇数");
            Assert.AreEqual("偶数", testMatch.Object.Test(4));
            Assert.AreEqual("奇数", testMatch.Object.Test(3));

上边测试代码模拟实现IMathTest接口实例,其中如果Test方法的参数是偶数,其返回值为“偶数”。这里的IT用来过滤参数的类,其具体解释可以参见MoQ的文档

3、属性
 public interface IPropertiesTest
    {
         int Test { get; set; }
    }
            var testProperties = new Mock<IPropertiesTest>();
            testProperties.Setup(p => p.Test).Returns(1);
            Assert.AreEqual(1, testProperties.Object.Test);

或者

var testProperties = new Mock<IPropertiesTest>();
            testProperties.SetupProperty(p => p.Test,1);
            Assert.AreEqual(1, testProperties.Object.Test);

4、Callback

当执行某方法时调用其内部输入的Action委托

int count = 0;
            var testProperties = new Mock<IPropertiesTest>();
            testProperties.Setup(p => p.Test).Returns(1).Callback(()=>count++);
            Assert.AreEqual(1, testProperties.Object.Test);
            Assert.AreEqual(1, count);

在调用Test方法是执行了count++

5、Verification

判断某方法或属性是否执行过

如果代码如下:

1 var testProperties = new Mock<IPropertiesTest>();
2             testProperties.Setup(p => p.Test).Returns(1);
3             testProperties.Verify(p => p.Test);
4             Assert.AreEqual(1, testProperties.Object.Test);

会抛出异常,因为第3行执行时Test方法还没有被调用过,改为如下代码可以通过测试

     var testProperties = new Mock<IPropertiesTest>();
            testProperties.Setup(p => p.Test).Returns(1);             Assert.AreEqual(1, testProperties.Object.Test);
            testProperties.Verify(p => p.Test);

其他细节可以查看MoQ文档。

二、应用

先创建一个Account类:

创建一个数据库Provider接口:

   public interface ITransferProvider
    {         void TransferTo(Account accountFrom, Account accountTo);     }

然后创建转账处理类:

 1 public class TransferProcess
 2     {
 3         private Account From;
 4         private Account To;
 5         private ITransferProvider transfer;
 6         public TransferProcess(Account from, Account to, ITransferProvider transfer)
 7         {
 8             this.From = from;
 9             this.To = to;
10             this.transfer = transfer;
11         }
12         public void Transfer(decimal money)
13         {
14             if (money<From.Money)
15             {
16                 From.Money = From.Money - money;
17                 To.Money = To.Money + money;
18                 transfer.TransferTo(From, To);
19             }
20             else
21             {
22                 throw new Exception("超出余额");
23             }
24         }
25     }

下边我们来测试这个转账处理类:

   var transfer = new Mock<ITransferProvider>();
            Account accountFrom = new Account() { AccountNum = 1, Money = 1000, Name = "lfm1" };
            Account accountTo = new Account() { AccountNum = 2, Money = 1000, Name = "lfm1" };             TransferProcess tp = new TransferProcess(accountFrom, accountTo, transfer.Object);
            tp.Transfer(500);
            Assert.AreEqual(500, accountFrom.Money);
            Assert.AreEqual(1500, accountTo.Money);
            

三、参考

http://code.google.com/p/moq/wiki/QuickStart

Beginning Mocking With Moq 3 – Part 1

Beginning Mocking With Moq 3 - Part 2

Beginning Mocking With Moq 3 - Part 3

Beginning Mocking With Moq 3 - Part 4

MoQ(基于.net3.5,c#3.0的mock框架)简单介绍的更多相关文章

  1. MoQ(基于.net3.5,c#3.0的mock框架)简单介绍(转)

    https://www.cnblogs.com/nuaalfm/archive/2009/11/25/1610755.html

  2. Android(Lollipop/5.0) Material Design(一) 简单介绍

    Material Design系列 Android(Lollipop/5.0)Material Design(一) 简单介绍 Android(Lollipop/5.0)Material Design( ...

  3. Hadoop2.6.0子项目hadoop-mapreduce-examples的简单介绍

    引文 学习Hadoop的同学们,一定知道如果运行Hadoop自带的各种例子,以大名鼎鼎的wordcount为例,你会输入以下命令: hadoop org.apache.hadoop.examples. ...

  4. 基于Selenium2+Java的UI自动化(4) - WebDriver API简单介绍

    1. 启动浏览器 前边有详细介绍启动三种浏览器的方式(IE.Chrome.Firefox): private WebDriver driver = null; private String chrom ...

  5. Dubbo学习笔记0:RPC框架Dubbo介绍

    整体来说,一个公司业务系统的演进流程基本都是从单体应用到多应用.在单体应用时,不同业务模块相互调用直接在本地JVM进程内就可以完成,而变为多个应用时,相互之间进行通信就不能简单的进行本地调用了,因为不 ...

  6. Nodejs-express 4.0框架 简单介绍

    http://www.expressjs.com.cn/4x/api.html  这个是express API的中文手册 但是只是翻译了一点 英语比较差比较难受. 1. 关于安装 现在网上查的时候有一 ...

  7. Mock 框架 Moq 的使用

    Mock 框架 Moq 的使用 Intro Moq 是 .NET 中一个很流行的 Mock 框架,使用 Mock 框架我们可以只针对我们关注的代码进行测试,对于依赖项使用 Mock 对象配置预期的依赖 ...

  8. [iOS 基于CoreBluetooth的蓝牙4.0通讯]

    一.首先大致介绍下蓝牙4.0的模式,中心和周边: 一般情况下,iPhone作为中心,接收来自周边传感器(比如手环等)采集的数据. 二.那整一个数据通讯的协议是怎样的呢? 为什么要一层层搞这么复杂呢?据 ...

  9. 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)

    最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...

随机推荐

  1. webstorm2016.2.4激活码

    测试日期:2016.11.07 webstorm版本:2016.2.4 系统环境:MacOS(windows环境应该也行) 激活码如下: 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0 ...

  2. Linux手动搭建LAMP环境

    当你看到标题里的“手动搭建”,你是不是会想,难不成还有“自动搭建”?当然......不是,这里的“手动搭建”是指按部就班的搭建Apache.MySQL.PHP环境,是相对于集成软件包而言的.所以你是不 ...

  3. java的(PO,VO,TO,BO,DAO,POJO)包解释

    java的(PO,VO,TO,BO,DAO,POJO)解释 action包  顾名思义请求,主要是和view 即我们所说的视图就是页面打交道,action类 是 操作方法,对于页 面Form 表单的操 ...

  4. 11--Python 备份文件程序

    最近看了下<A Byte of Python>, 看见一个非常有意思的程序,用python进行文件行备份的练习程序, 自己在机器上敲代码运行了一遍,结果出现了一个小问题,路径出错--&qu ...

  5. 说说final关键字(好像有干货)

    在java开发过程中,final是大家常用的关键字,无非就是用来修饰类,方法和变量,来表名类不能被继承,方法不会被覆盖,变量不能被改变,悄悄的说一句,private方法也隐式的final.通过一段时间 ...

  6. 解决VS2010中winsock.h与winsock2.h冲突(重复定义)——转载

    解决VS2010中winsock.h与winsock2.h冲突(重复定义)——转载 当这两个头文件顺序颠倒时,编译会出现许多莫名其妙的错误,错误如下: 1>…\include\ws2def.h( ...

  7. VBS控制鼠标移动和点击(附源代码下载)

    森思:想用vbs来控制鼠标的移动和点击,虽然按键精灵可以做到,但做这么简单的事情不想启动那么大一个程序,所以自己用VC写了一个小程序,可以让VBS来控制鼠标移动和点击. 用法: 移动鼠标到桌面坐标20 ...

  8. Java类和类成员的访问权限修饰符

    一:访问修饰符: 1.省略访问修饰符 具有默认的访问特性,即具有包访问特性,只能被同一个包中的类使用. 2.public访问修饰符 用于说明类和类的成员的访问权限.这种类叫公有类.在一个文件中只能有一 ...

  9. android 瀑布流效果(仿蘑菇街)

    我们还是来看一款示例:(蘑菇街)           看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出 ...

  10. CentOS7 PostgreSQL 主从配置( 三)

    postgres 主备切换 主备查看 方法 ps -ef | grep wal (主库 sender)postgres 27873 27864 0 5月06 ? 00:00:10 postgres: ...