Moq & RhinoMocks

使用Mock对象进行测试一般都会有以下三个关键步骤:

  1. 使用接口来描述需要测试的对象
  2. 为实际的产品代码实现这个接口
  3. 以测试为目的,在Mock对象中实现这个接口

在使用Mock对象的过程中,充分体现出了“面向接口编程”的设计原则,同时也促成类的良好设计。

自行实现Mock对象是相当繁琐的工作,让人幸运的是,在.NET世界中有多个优秀的Mock框架可以供大家选择,目前最常使用的无非MoqRhino Mocks这两个框架。两者的最新版本在Mocking API方面的用法已日趋一致,都依托Lambda表达式、泛型和扩展方法做了很大改进,目标都是让Mock对象以一种更自然的方式与多个单元测试框架进行集成,以一种清晰的语法来描述期望值、参数约束、返回值等,极大的方便开发者的使用。

由于Moq和Rhino Mocks都使用了Castle DynamicProxy这个类库动态生成代理类,因此对需要Mock的对象有一定的限制:所测试的方法必须是virtual类型。

下面就用一个例子来看看两者的不同实现(这个例子摘自Moq源代码包中的Samples,只是略做了些修改以便于展现两者的特点):

需要进行测试的对象如下示之:

展开

下面是用这两个Mock框架分别实现的单元测试代码:

Moq 4.0 Rhino Mocks 3.6
[Test]
public void TestPresenterSelection() {
// arrange
var mView = new Mock<IOrdersView>();
var mRepository = new Mock<IRepository<Order>>();
var presenter = new OrdersPresenter(mView.Object, mRepository.Object);
// check that the presenter has no selection by default
Assert.Null(presenter.SelectedOrder); // raise event
mView.Raise(io => io.OrderSelected += null,
new OrderEventArgs { Order = new Order("moq", 50) }); // assert
Assert.NotNull(presenter.SelectedOrder);
Assert.AreEqual("moq", presenter.SelectedOrder.ProductName);
}
[Test]
public void TestPresenterSelection() {
// arrange
var mView = MockRepository.GenerateMock<IOrdersView>();
var mRepository = MockRepository.GenerateMock<IRepository<Order>>();
var presenter = new OrdersPresenter(mView, mRepository);
// check that the presenter has no selection by default
Assert.Null(presenter.SelectedOrder); // raise event
mView.Raise(io => io.OrderSelected += null, null,
new OrderEventArgs { Order = new Order("moq", 50) }); // assert
Assert.NotNull(presenter.SelectedOrder);
Assert.AreEqual("moq", presenter.SelectedOrder.ProductName);
}
[Test]
public void TestRetrieveOrders() {
// arrange
var mView = new Mock<IOrdersView>();
var mRepository = new Mock<IRepository<Order>>();
var presenter = new OrdersPresenter(mView.Object, mRepository.Object); List<Order> defaultOrders = new List<Order>
{ new Order("moq"), new Order("RhinoMock") }; mRepository.Setup(r => r.FindAll()).Returns(defaultOrders); // exercise mocks
presenter.OnInit();
// assert
mView.VerifySet(v => v.Orders = defaultOrders);
}
[Test]
public void TestRetrieveOrders() {
// arrange
var mView = MockRepository.GenerateMock<IOrdersView>();
var mRepository = MockRepository.GenerateStub<IRepository<Order>>();
var presenter = new OrdersPresenter(mView, mRepository); List<Order> defaultOrders = new List<Order>
{ new Order("moq"), new Order("RhinoMock") }; mRepository.Stub(ir => ir.FindAll()).Return(defaultOrders); // exercise mocks
presenter.OnInit();
// assert
mView.AssertWasCalled(v => v.Orders = defaultOrders);
}

Conclusion

通过上面的实例我们可以很容易看出两者的Syntax与API都非常接近,使用两者任何一个都能方便实现你的测试目的。

References

  1. QuickStart - Moq
  2. Ayende@Wiki - Rhino Mocks 3.5
  3. Daniel Cazzulino's Blog - Why do we need yet another NET mocking framework
 
分类: C#
标签: MoqRhino Mocks

Moq 和RhinoMocks的更多相关文章

  1. Moq 和 RhinoMocks

    我们在做单元测试的时候,利用mock可轻松构建出测试需要的类或接口,而不需要编写繁琐的测试代码. .net 下我知道Moq与Rhino Mocks这两个框架. Moq 网上介绍的比较多. Rhino ...

  2. Moq & RhinoMocks

    Moq & RhinoMocks 使用Mock对象进行测试一般都会有以下三个关键步骤: 使用接口来描述需要测试的对象 为实际的产品代码实现这个接口 以测试为目的,在Mock对象中实现这个接口 ...

  3. Moq 测试 属性,常用方法

    RhinoMock入门(7)——Do,With和Record-playback 摘要: (一)Do(delegate)有时候在测试过程中只返回一个静态的值是不够的,在这种情况下,Do()方法可以用来在 ...

  4. Moq基础

    一.概念 Moq是利用诸如Linq表达式树和Lambda表达式等·NET 3.5的特性,为·NET设计和开发的Mocking库.Mock字面意思即模拟,模拟对象的行为已达到欺骗目标(待测试对象)的效果 ...

  5. 单元测试与Moq

    这个篇幅里面,记录单元测试与Moq模拟包的知识点. 单元测试 每一个模块,都应该有对应的单元测试.单元测试可以保证你的代码准确性,大大减少出现BUG的几率.一个好的单元测试,也是重构代码必不可少的部分 ...

  6. moq 的常用使用方法

    测试方法                             Console.WriteLine(mock.Object.GetCountThing()); 匹配参数   mock.Setup(x ...

  7. 单元测试中使用Moq对EF的DbSet进行mock

    刚用上Moq,就用它解决了一个IUnitOfWork的mock问题,在这篇博文中记录一下. 开发场景 Application服务层BlogCategoryService的实现代码如下: public ...

  8. 【MVC 4】4.MVC 基本工具(Visual Studio 的单元测试、使用Moq)

     作者:[美]Adam Freeman      来源:<精通ASP.NET MVC 4> 3.Visual Studio 的单元测试 有很多.NET单元测试包,其中很多是开源和免费的.本 ...

  9. 【Pro ASP.NET MVC 3 Framework】.学习笔记.4.MVC的主要工具-使用Moq

    在之前的例子中,我们创建了FakeRepository类来支持我们的测试.但是我们还没有解释如何穿件一个真实的repository实现,我们需要一个替代品.一旦我们有一个真的实现,我们可能不会再用它, ...

随机推荐

  1. Linux平台下裸设备的绑定:

    Linux平台下裸设备的绑定: 运用RAW绑定 方法一 raw的配置(1) [root@qs-dmm-rh2 mapper]# cat /etc/rc.local #!/bin/sh # # This ...

  2. UNITY3D MAC版本号破解

    首先,解释一下.是公司做开发建议去购买正版. 之前网上也有非常多人贴出了破解方法,有些也是能够的.可是大多数解说不太具体,在这里贴出相对具体点的教程.本人亲測成功(測试版本Unity4.0.1 mac ...

  3. 谈论json - json经常使用的功能

    json经常使用的功能有JSON.parse().JSON.stringify(),供json对象和字符串之间的相互转换. 1.JSON.parse() 将 JavaScript 对象符号 (JSON ...

  4. OAuth在WebApi

    OAuth在WebApi中的使用,前后台分离的调用方式 前段时间由于公司架构服务层向WebApi转换,就研究了OAuth在WebApi中的使用,这中间遇到了很多坑,在此记录一下OAuth的正确使用方式 ...

  5. 实现DataGridView行的拖动,即实现行的顺序交换

    参考:http://blog.csdn.net/soarheaven/article/details/3267379 1.界面准备 (1)首先在form中添加一个DataGridView控件,将默认A ...

  6. ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇 第三章 为控件添加事件 后篇 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是 ...

  7. 网站压力测试工具Webbench介绍

    webbench简单介绍: webbench是由 Lionbridge公司开发的出色的站点压力測试工具.它能測试处在同样硬件上,不同服务的性能以及不同硬件上同一个服务的执行状况.webbench不但能 ...

  8. IOS基金会_ UICollectionView简单易用

    和表格视图类似 UICollectionView的使用有两种方法 一种是继承UICollectionViewController,这个Controller会自带一个UICollectionView. ...

  9. 嵌入在网页上Flash媒体播放器(1)

    做的项目,在不久的将来相关的Flash玩家使用,需要播放视频的网页上,不同的视频资源,需要不同的球员.基于使用稳定性.的嵌入式和嵌入式复杂性能的优点概括起来有两种方式(不同的玩家),视频资源也略有不同 ...

  10. HDU 4819 Mosaic D区段树

    连接:pid=4819">http://acm.hdu.edu.cn/showproblem.php?pid=4819 意:给出一个800×800下面的矩阵.每次更新一个点的值为以这个 ...