现在的位置: 首页 > 综合 > 正文

Rhino Mocks (RhinoMock)2

2013年03月02日 ⁄ 综合 ⁄ 共 5154字 ⁄ 字号 评论关闭

      本文将介绍一款在.Net平台下的Mock工具---Rhino Mocks 2,以及相关Mock工具的一些比较.在了解到Rhino Mocks 2之前我也接触了一些其他的Mock工具, 比如EasyMockJMockNMock NMock2,不过最终还是选择了Rhino Mocks 2, 相信你在看完本文的介绍后会和我做出同样的选择。(注: 本文不是Mock工具的入门文章,如果你之前尚未接触了解有关Mock对象,请先去了解相关资料)

本文由于编写时间较早, 现在RhinoMock有了新的变化,请参考RhinoMock2 续一文.
      

从一个例子说起:

   27   public interface ISubscriber

   28     {

   29         int MultiplyTwo(int i);

   30         void Receive(Object message);

   31     }

   32 

   33     public class Publisher

   34     {

   35         private List<ISubscriber> subscribers = new List<ISubscriber>();

   36 

   37         public void Add(ISubscriber s)

   38         {

   39             subscribers.Add(s);

   40         }

   41 

   42         public void Publish(object msg)

   43         {

   44             subscribers.ForEach(delegate(ISubscriber s) { s.Receive(msg); });

   45         }

   46         public int Caculate(int i)

   47         {

   48             int result = 0;

   49             subscribers.ForEach(delegate(ISubscriber s) { result += s.MultiplyTwo(i); });

   50             return result;

   51         }

   52     }

以上是一个Observer模式的小例子, 为了更加全面的体现出Mock对象的特性, 我在ISubscriber加了一个有返回值的方法MultiplyTwo, 它所做的事情就是将参数乘2并返回.

现在我们将对Publisher进行测试, 然而Publisher中涉及到了另一个对象ISubscriber. 而我们暂时还没实现ISubscriber , 所以我们将利用Mock Object来完成我的测试.

下面是4Mock框架下的不同测试代码:

 

EasyMock.Net

   55 namespace EasyMockTest

   56 {

   57     [TestFixture]

   58     public class PublisherTest

   59     {

   60         [Test]

   61         public void OneSubscriberReceivesAMessage()

   62         {

   63             //setup

   64             MockControl  mockCtrl= MockControl.CreateControl(typeof(ISubscriber));

   65             ISubscriber subMock = mockCtrl.GetMock() as ISubscriber;

   66             Publisher publisher = new Publisher();

   67             publisher.Add(subMock);

   68             object message = new object();

   69 

   70             //record

   71             mockCtrl.Reset();

   72             subMock.Receive(message);

   73             subMock.MultiplyTwo(5);

   74             mockCtrl.SetReturnValue(10);

   75             mockCtrl.Replay();

   76 

   77             //execute

   78             publisher.Publish(message);

   79             Assert.AreEqual(10, publisher.Caculate(5));

   80 

   81             //verify

   82             mockCtrl.Verify();

   83         }

   84     }

   85 }

 

NMock

   55 namespace NMockTest

   56 {

   57     [TestFixture]

   58     public class PublisherTest

   59     {

   60         [Test]

   61         public void OneSubscriberReceivesAMessage()

   62         {

   63             // set up

   64             Mock mockSubscriber = new DynamicMock(typeof(ISubscriber));

   65             Publisher publisher = new Publisher();

   66             publisher.Add((ISubscriber)mockSubscriber.MockInstance);

   67             object message = new Object();

   68 

   69             // expectations

   70             mockSubscriber.Expect("Receive", message);   //commentted is still ok

   71             mockSubscriber.ExpectAndReturn("MultiplyTwo", 10, 5);

   72 

   73             // execute

   74             publisher.Publish(message);

   75             Assert.AreEqual(10, publisher.Caculate(5));

   76 

   77             // verify

   78             mockSubscriber.Verify();

   79         }

   80     }

   81 }

 

NMock2

   55 namespace NMock2Test

   56 {

   57     [TestFixture]

   58     public class PublisherTest

   59     {

   60         [Test]

   61         public void OneSubscriberReceivesAMessage()

   62         {

   63             using (Mockery mocks = new Mockery())

   64             {

   65                 //setup

   66                 ISubscriber subMock = mocks.NewMock(typeof(ISubscriber)) as ISubscriber;

   67                 Publisher publisher = new Publisher();

   68                 publisher.Add(subMock);

   69                 object message = new object();

   70 

   71                 //expectations

   72                 Expect.Once.On(subMock).Method("Receive").With(message);

   73                 Expect.Once.On(subMock).Method("MultiplyTwo").With(5).Will(Return.Value(10));

   74 

   75                 //excute

   76                 publisher.Publish(message);

   77                 Assert.AreEqual(10, publisher.Caculate(5));

   78             }// verify when mocks dispose

   79         }

   80     }

   81 }

 

RhinoMocks2

   55 namespace RhinoMocks2Test

   56 {

   57     [TestFixture]

   58     public class PublisherTest

   59     {

   60         [Test]

   61         public void OneSubscriberReceivesAMessage()

   62         {

   63             using (MockRepository mocks = new MockRepository())

   64             {

   65                 //setup

   66                 ISubscriber subMock = mocks.CreateMock(typeof(ISubscriber)) as ISubscriber;

   67                 Publisher publisher = new Publisher();

   68                 publisher.Add(subMock);

   69                 object message = new object();

   70 

   71                 //record with expectation model

   72                 subMock.Receive(message);

   73                 Expect.On(subMock).Call(subMock.MultiplyTwo(5)).Return(10);

   74 

   75                 //end record

   76                 mocks.ReplayAll();

   77 

   78                 //excute

   79                 publisher.Publish(message);

   80                 Assert.AreEqual(10, publisher.Caculate(5));

   81             }//verify when mocks dispose

   82         }

   83     }

   84 }

       大致看来NMock2RhinoMocks2比较相像, 尤其在创建Mock对象的时候, 这点也是较之EasyMockNMock比较合理的地方, 因为你只需一个MockRepository就可以创建出多个Mock Object, 并且可以直接获得该类型的对象, 不需要再用mock.GetMock().这样的方法来获得所需的Mock对象.并且它们都利用using block增加方便性.(using block结束的时候会调用using对象的Dispose方法,此时将会自动调用mocks.VerifyAll(), 不需要象EasyMockNMock那样显式调用Verify方法.)

NMock2

抱歉!评论已关闭.