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

2023-10-09 18:30

本文主要是介绍MoQ(基于.net3.5,c#3.0的mock框架)简单介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们在做单元测试的时候,常常困扰于数据的持久化问题,很多情况下我们不希望单元测试影响到数据库中的内容,而且受数据库的影响有时我们的单元测试的速度会很慢,所以我们往往希望将持久化部分隔离开,做单元测试的时候不真正的将数据持久化。这种隔离我们一般使用抽象的方式,也就是利用接口或抽象类将持久化层隔离开,然后利用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();
    }

测试代码:

 

ContractedBlock.gif ExpandedBlockStart.gif 简单测试代码
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);
    }

 

ContractedBlock.gif ExpandedBlockStart.gif 匹配测试
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委托

 

ContractedBlock.gif ExpandedBlockStart.gif Callback
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

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

如果代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
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方法还没有被调用过,改为如下代码可以通过测试

 

ContractedBlock.gif ExpandedBlockStart.gif Code
     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);

    }

 

然后创建转账处理类:

 

ContractedBlock.gif ExpandedBlockStart.gif TransferProcess
 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     }

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

 

ContractedBlock.gif ExpandedBlockStart.gif Code
   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框架)简单介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/174745

相关文章

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

C#TextBox设置提示文本方式(SetHintText)

《C#TextBox设置提示文本方式(SetHintText)》:本文主要介绍C#TextBox设置提示文本方式(SetHintText),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录C#TextBox设置提示文本效果展示核心代码总结C#TextBox设置提示文本效果展示核心代

C#中DrawCurve的用法小结

《C#中DrawCurve的用法小结》本文主要介绍了C#中DrawCurve的用法小结,通常用于绘制一条平滑的曲线通过一系列给定的点,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 如何使用 DrawCurve 方法(不带弯曲程度)2. 如何使用 DrawCurve 方法(带弯曲程度)3.使用Dr

Pytest多环境切换的常见方法介绍

《Pytest多环境切换的常见方法介绍》Pytest作为自动化测试的主力框架,如何实现本地、测试、预发、生产环境的灵活切换,本文总结了通过pytest框架实现自由环境切换的几种方法,大家可以根据需要进... 目录1.pytest-base-url2.hooks函数3.yml和fixture结论你是否也遇到过

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,