zoukankan      html  css  js  c++  java
  • Moq & RhinoMocks

    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,只是略做了些修改以便于展现两者的特点):

    mocks 

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

    展开

    下面是用这两个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#

    Event Broker: 通过发布事件源和订阅事件源来完成对象之间的协作
    摘要: 在实际应用中,我们可以使用EventBroker来进行发布和订阅事件通知以实现对象间的通信。阅读全文

    posted @ 2011-06-16 21:52 hans.hu 阅读(322) | 评论 (0) 编辑

    趣味编程(一)
    摘要: 最近遇到的几个编程小实例。阅读全文

    posted @ 2010-10-29 21:51 hans.hu 阅读(369) | 评论 (4) 编辑

    行为驱动开发之道
    摘要: 介绍了行为驱动开发(Behavior Driven Development)常用的两个框架:SpecUnit与MSpec。 阅读全文

    posted @ 2010-06-18 16:22 hans.hu 阅读(1127) | 评论 (0) 编辑

    Dependency Injection Frameworks
    摘要: 本人前一段时间整理好的、目前比较常用的IoC容器,在此做个记录以供日后参考使用。阅读全文

    posted @ 2010-06-15 09:01 hans.hu 阅读(520) | 评论 (0) 编辑

    Moq & RhinoMocks
    摘要: 在.NET世界中有多个优秀的Mock框架可以供大家选择,目前最常使用的无非Moq与Rhino Mocks这两个框架。阅读全文

    posted @ 2010-06-14 10:29 hans.hu 阅读(1870) | 评论 (2) 编辑

    Windows Live Writer 插件
    摘要: 本人开发的Windows Live Writer两个小插件(附源代码)。阅读全文

    posted @ 2009-08-15 08:40 hans.hu 阅读(1948) | 评论 (17) 编辑

    循序渐进学Boo - DSL篇
    摘要: 本系列的终篇,在前几篇Boo文章的基础之上,本文着重介绍Boo与C#的混合编程对DSL的实现。 阅读全文

    posted @ 2009-08-09 16:48 hans.hu 阅读(2162) | 评论 (4) 编辑

    从一个小实例开始 - Boo开篇
    摘要: Boo是一个类似Python语法、静态类型、运行在CLR之上的面向对象语言,它有一个强大的编译器扩展能力和更容易构建DSL的特性。本篇通过一个实例向大家介绍这门基于CLR的语言,希望能有越来越多的人关注Boo!阅读全文

    posted @ 2009-04-14 11:41 hans.hu 阅读(2416) | 评论 (10) 编辑

     
    分类: C#
    标签: MoqRhino Mocks
  • 相关阅读:
    2021上半年下午第二题
    21年软件设计师上半年下午试题一
    软考下午第三题-用例图和类图
    类图
    用例图-包含、扩展、泛化
    软考下午题二------数据库设计
    软件设计师下午题-数据流图
    IP练习题
    2020软件工程作业02
    2020软件工程作业01
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3430959.html
Copyright © 2011-2022 走看看