Moq & RhinoMocks

来源:互联网 发布:网络usb服务器 编辑:程序博客网 时间:2024/06/05 04:07

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

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

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

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

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

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

mocks 

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

展开
折叠public class OrdersPresenter{    private IRepository<Order> repository { get; set; }    public IOrdersView View { get; set; }    public OrdersPresenter(IOrdersView view, IRepository<Order> repository) {        this.View = view;        this.repository = repository;        this.View.OrderSelected += (sender, args) => DoOrderSelection(args.Order);    }    public Order SelectedOrder { get; private set; }    private void DoOrderSelection(Order selectedOrder) {        // Do something when the view selects an order.        SelectedOrder = selectedOrder;    }    public virtual void OnInit() {        View.Orders = repository.FindAll();    }           }

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

Moq 4.0Rhino 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

Mock, stub根据接口创建类,构建签名返回值,构建事件方法

http://www.cnblogs.com/RicCC/archive/2010/04/01/structuremap-demo.html
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 欠太多人的钱怎么办 我欠了很多钱怎么办 输了那么多钱我该怎么办 家里欠了钱我该怎么办 欠了好多钱我该怎么办 赌球输了好几千怎么办 欠信用卡的人死了怎么办 欠别人钱人死了怎么办 别人欠我钱人死了怎么办 美国生娃孩子怎么办医保 黑在美国病了怎么办 在外打工房租太贵怎么办 在外面打工房租租不起怎么办 买车型号错了怎么办 沃出行不退押金怎么办 钢铁雄心4人力0怎么办 钢铁雄心4没工厂怎么办 钢铁雄心4锁区怎么办 qq超市金币满了怎么办 旋转轮胎2车翻了怎么办 轮胎里面卡进小石子应该怎么办 手游吃鸡模拟器已经到达上限怎么办 逆战场手游模拟器黑屏怎么办 欧洲卡车2翻车了怎么办 卧式注塑机锁模久了打不开怎么办 欧洲卡车2困了怎么办 欧卡2没油了怎么办 欧卡2车卡住了怎么办 欧卡2车子卡住了怎么办 做题手感变差怎么办 吃鸡游戏掉帧怎么办 买了俄区游戏怎么办 战地1子弹用完了怎么办 1kb彩信点开了怎么办 玩地球末日卡顿怎么办 电脑显示不亮了怎么办 电脑玩游戏显卡停止运行怎么办 ie浏览器打开就停止工作怎么办 蝙蝠侠阿甘骑士卡顿怎么办 捷豹钥匙没电了怎么办 车钥匙没电 汽车报警怎么办