What is “Mock You”系列之(一) 初识Mock 和 Moq
2010-02-21 17:13 姜 萌@cnblogs 阅读(1825) 评论(1) 编辑 收藏 举报项目扉页 | 相关下载 |
http://code.google.com/p/moq/ | http://code.google.com/p/moq/downloads/list |
先说说一般的使用Mock进行测试的基本过程:
Moq的3.x版本已经不同以往,这得益于.net3.x为大家带来的Lambda表达式,Linq。
说说Moq的优点:
a.完全开源。开源的好处我就不多说了,不过相比java社区上的活跃,Apache项目的浩繁,.net在这方面确实逊色不少。
b.简单易学,便于使用。Moq的设计原则就是“以极低的门槛获取良好的重构能力”在我个人看来,Moq是我用过的上手最容易使用起来最自然的Mock。
Moq中几个重要的类(在后续文章中详细介绍):
Mock<T>:通过这个类我们能够得到一个Mock<T>对象,T可以是接口 和 类。它有一个公开的Object属性,这个就是我们Moq为我们模拟出的对象。
It:这是一个静态类,用于过滤参数。
MockBehavior:用于配置MockObject的行为,比如是否自动mock。
MockFactory:Mock对象工厂,能够批量生产统一自定义配置的Mock对象,也能批量的进行Mock对象测试。
Match<T>:如果你先嫌It不够用就用Match<T>,通过它能够完全自定义规则。
初识Moq:
新建一个测试,我们用三行代码演示一个Moq的使用。
[TestMethod()] //Setup our Mock Object //Assert it! |
说明:
new Mock<T>返回一个Mock对象,我们可以用var接收,这样写起来更方便些,Mock<T>有一个Object属性,存储的就是我们的模拟对象实例。
Setup的参数是一个Lambda Expression,我们可以理解为:“当 被mock的对象p调用MethodWithParamAndResult方法 并且参数为”abc”的时候”。后面再加一个Return(“123”)我们可以理解为:(在之前Setup的情况下)返回的值为”123”。这样,我们就填充好了一个“伪对象”的行为,我们只让它做一件实事儿:当我们调用mo.Object.MethodWithParaAndResult方法并且参数为”abc”时会返回”123”。
实际上我们不仅能够在Setup后面接Returns方法还能接诸如Throws、Verify之类的方法,这是为什么呢?Setup方法会返回一个ISetup对象,看看ISetup的定义:
public interface ISetup<TMock, TResult> : ICallback<TMock, TResult>, IReturnsThrows<TMock, TResult>, IReturns<TMock, TResult>, IThrows, INever, IVerifies, IHideObjectMembers where TMock : class
恩,是链式编程,ISetup接口继承了很多接口,这里我们注意到IReturns<TMock,TResult>,看看IReturns<TMock, TResult>定义:
public interface IReturns<TMock, TResult> : IHideObjectMembers where TMock : class。
里面有一个方法:IReturnsResult<TMock> Returns<T>(Func<T, TResult> valueFunction);
所以我们还能写出这样的代码:
mo.Setup(p => p.MethodWithParamAndResult("abc"))
.Returns("123")
.Callback(……)
.Throws(……)
.Verifiable(……);
呵呵,这种代码理解起来是很自然的。Moq设计的是不是很人性化呢。