欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Rhino Mocks 2 - Alpha Atom
Rhino Mocks 2
作者 idior   
2005-08-07 14:46

本文將介紹一款在.Net平臺下的Mock工具---Rhino Mocks 2,以及相關(guān)Mock工具的一些比較.在了解到Rhino Mocks 2之前我也接觸了一些其他的Mock工具, 比如EasyMock,JMock,NMock, NMock2,不過(guò)最終還是選擇了Rhino Mocks 2, 相信你在看完本文的介紹后會(huì )和我做出同樣的選擇

 從一個(gè)例子說(shuō)起:   

        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
     }

以上是一個(gè)Observer模式的小例子, 為了更加全面的體現出Mock對象的特性, 我在ISubscriber加了一個(gè)有返回值的方法MultiplyTwo, 它所做的事情就是將參數乘2并返回.

現在我們將對Publisher進(jìn)行測試, 然而Publisher中涉及到了另一個(gè)對象ISubscriber. 而我們暫時(shí)還沒(méi)實(shí)現ISubscriber , 所以我們將利用Mock Object來(lái)完成我的測試.

下面是4種Mock框架下的不同測試代碼:

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
 }

大致看來(lái)NMock2和RhinoMocks2比較相像, 尤其在創(chuàng )建Mock對象的時(shí)候, 這點(diǎn)也是較之EasyMock和NMock比較合理的地方, 因為你只需一個(gè)MockRepository就可以創(chuàng )建出多個(gè)Mock Object, 并且可以直接獲得該類(lèi)型的對象, 不需要再用mock.GetMock().這樣的方法來(lái)獲得所需的Mock對象.并且它們都利用using block增加方便性.(在using block結束的時(shí)候會(huì )調用using對象的Dispose方法,此時(shí)將會(huì )自動(dòng)調用mocks.VerifyAll(), 不需要象EasyMock和NMock那樣顯式調用Verify方法.)

而NMock2和RhinoMocks2的區別主要在于Expectation階段.

僅僅從語(yǔ)法上來(lái)看, 你會(huì )發(fā)現它們都使用了Expectation的語(yǔ)法, 但是RhinoMocks2顯然更勝一籌.                

 

void Receive(Object message);
NMock2
Expect.Once.On(subMock).Method("Receive").With(message);
RhinoMocks2
subMock.Receive(message);

RhinoMocks2的語(yǔ)法非常簡(jiǎn)潔也更加自然. 不過(guò)如果之前一直使用Expectation語(yǔ)法的可能會(huì )覺(jué)得奇怪, 怎么把方法的執行放到了Expectation階段. 注意到RhinoMocks2的這個(gè)特點(diǎn),你就會(huì )覺(jué)得很自然了, 對于沒(méi)有返回值的方法RhinoMocks2是這樣處理的.

mock.Method(Parameter p);

LastCall.On(mock);

不過(guò)LastCall.On(mock);可以被省略.RhinoMocks2會(huì )自動(dòng)為你補上.

再來(lái)看看對于有返回值的方法的處理:

 

int MultiplyTwo(int i);
NMock2
Expect.Once.On(subMock).Method("MultiplyTwo").With(5).Will(Return.Value(10));
RhinoMocks2
Expect.On(subMock).Call(subMock.MultiplyTwo(5)).Return(10);

簡(jiǎn)而言之,RhinoMocks2是類(lèi)型安全的. NMock2中使用的是字符串型的方法名,這樣既沒(méi)有了IDE自動(dòng)完成的支持,而且要在測試運行時(shí)才能檢查出錯誤. 并且對于參數和返回值的語(yǔ)法也是RhinoMocks2處理的更加簡(jiǎn)潔,自然.

為什么NMock2甚至JMock沒(méi)有使用類(lèi)型安全的語(yǔ)法? 不是它們沒(méi)有想到,而是由于它們和RhinoMocks2采取的實(shí)現模型是不一樣的. EasyMock.Net 和RhinoMocks2采用的是Record/Replay的模型,即先記錄Record將會(huì )發(fā)生的事, 然后在回放(Replay). 你可以看到RhinoMocks2的76行使用了mocks.ReplayAll(); 而NMock2并沒(méi)有調用該方法. NMock2和JMock都采用了Expectation的模型, 所有的期望發(fā)生的方法都使用Expect來(lái)定義.所以導致了它們之間的不同. 而RhinoMocks2就是結合兩者的優(yōu)點(diǎn)使得你既能獲得類(lèi)型安全又能使用類(lèi)似Expect的簡(jiǎn)潔語(yǔ)法.

RhinoMocks2和NMock2相比較NMock都學(xué)習了JMock強大的Constraints.

Constraint:
Example:
Object
Anything
Is.Anything()
Equal
Is.Equal(3)
Not Equal
Is.NotEqual(3) or !Is.Equal(3)
Null
Is.Null()
Not Null
Is.NotNull()
Type Of
Is.TypeOf(typeof(string))
Greater Than
Is.GreaterThan(10)
Greater Than Or Equal
Is.GreaterThanOrEqual(10)
Less Than
Is.LessThan(10)
Less Than Or Eqaul
Is.LessThanOrEqual(10)
Property
Equal To Value
Property.Value("Length",0)
Null
Property.IsNull("InnerException")
Not Null
Property.IsNotNull("InnerException")
List
Is In List
[the parameter is a collection that contains this value]
List.IsIn(4)
One Of
[parameter equal to one of the objects in this list]
List.OneOf(new int[]{3,4,5})
Equal
List.Equal(new int[]{4,5,6})
Text
Starts With
Text.StartsWith("Hello")
Ends With
Text.EndsWith("World")
Contains
Text.Contains("or")
Like
[perform regular expression validation]
Text.Like("Rhino|rhino|Rhinoceros|rhinoceros" )
Operator Overloading
And - operator &
Text.StartsWith("Hello") & Text.Contains("bar")
Or - operator |
Text.StartsWith("Hello") & Text.Contains("bar")
Not - operator !
!Text.StartsWith("Hello")

RhinoMocks2的缺點(diǎn):

對于所有的mock對象, 你必須預計(Expect)到它在執行時(shí)(excute)的所有將發(fā)生方法, 否則都會(huì )導致測試無(wú)法通過(guò), 唯一例外的一點(diǎn)就是NMock對此沒(méi)有要求.當你把NMockTest的第70行注釋掉,測試依然通過(guò).

不知道是不是因為這樣的原因RhinoMocks2并沒(méi)有提供Expect.Never.On這樣的語(yǔ)法. 也就是我無(wú)法保證某個(gè)方法不被調用. 而其他的框架都實(shí)現了類(lèi)似的功能.

我的期望:

Expect.On(subMock).Call(subMock.MultiplyTwo(5)).Return(10);
其中On方法似乎顯的多余.不知道能不能改成下面這個(gè)樣子.
Expect.Call(subMock.MultiplyTwo(5)).Return(10);
甚至于變成這樣
subMock.MultiplyTwo(5)==10;

當然Expectation的模型應該保留,因為對于某些需要指定異常,約束的情況你是無(wú)法通過(guò)subMock.MultiplyTwo(5)==10;這樣的形式來(lái)描述的.

雖然Expect的語(yǔ)法的語(yǔ)義比較強, 但是在書(shū)寫(xiě)的時(shí)候還是比較麻煩.不知道能不能有更好的模型.

Mock對象在測試時(shí)無(wú)法調試, 這點(diǎn)和NUnit那樣基于狀態(tài)的測試相比差了點(diǎn), 只能靠自己動(dòng)腦子了.

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
【GOF設計模式之路】-- Observer
Rhino插件
Publisher 2010 (x86)
Publisher 2007教程專(zhuān)題
Hina Aoyama 的精細剪紙藝術(shù)
Poems, by Victor Hugo
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久