RhinoMock入門(7)——Do,With和Record-playback

做者: 梅樺 發表於 2010-05-11 15:50 原文連接 閱讀: 86 評論: 0html

(一)Do(delegate)程序員

有時候在測試過程當中只返回一個靜態的值是不夠的,在這種狀況下,Do()方法能夠用來在方法調用時添加自定義的行爲。通常來講,Do()方法會替換方法調用。它的返回值會從模擬的調用中返回(即便是有異常發生也是這樣)。Do()的參數委託委託的方法的簽名須和方法的簽名匹配。只有當簽名匹配時才能生效,且一個匹配生效一次。測試

看官方給出的例子:網站

public   class  Speaker
{
    
private   readonly   string  firstName;
    
private   readonly   string  surname;
    
private  INameSource nameSource;

    
public  Speaker( string  firstName,  string  surname, INameSource nameSource)
    {
        
this .firstName  =  firstName;
        
this .surname  =  surname;
        
this .nameSource  =  nameSource;
    }

    
public   string  Introduce()
    {
        
string  name  =  nameSource.CreateName(firstName, surname);
        
return   string .Format( " Hi, my name is {0} " , name);
    }
}

  

public   interface  INameSource
{
    
string  CreateName( string  firstName,  string  surname);
}

 

如今演講者和名字分開在兩個類中。而後進行自我介紹,介紹時要介紹本身的姓名,即 FirstName+LastName 。在介紹中要用到 InameSource 中的 CreateName 方法,接下來將會模擬這個接口,而經過其它的方法來替代。

 

[Test]
public   void  SayHelloWorld()
{
    MockRepository mocks 
=   new  MockRepository();
    INameSource nameSource 
=  mocks.DynamicMock < INameSource > ();

    Expect.Call(nameSource.CreateName(
null null ))
          .IgnoreArguments()
          .Do(
new  NameSourceDelegate(Formal));

    mocks.ReplayAll();
    
string  expected  =   " Hi, my name is Ayende Rahien " ;
    
string  actual  =   new  Speaker( " Ayende " " Rahien " , nameSource).Introduce();
    Assert.AreEqual(expected, actual);
}

delegate   string  NameSourceDelegate( string  first,  string  surname); 

private   string  Formal( string  first,  string  surname)
{
    
return  first  +   "   "   +  surname;
}

 

看上段測試的粗體部分。this

Do參數是委託類型,其中這個委託類型委託的方法的簽名要和模擬對象中指望的要替換的方法的簽名一致,即:spa

private   string  Formal( string  first,  string  surname)
string  CreateName( string  firstName,  string  surname);

 

二者相匹配。code

而後當對演講者構造時:
new Speaker("Ayende", "Rahien", nameSource)orm

會對演講者三個域進行賦值視頻

private   readonly   string  firstName;
private   readonly   string  surname;
private  INameSource nameSource;

 

接下來進行介紹時,調用方法:htm

public   string  Introduce()
{
    
string  name  =  nameSource.CreateName(firstName, surname);
    
return   string .Format( " Hi, my name is {0} " , name);
}

 

而這個方法則由Do方法的委託參數委託的方法來替代:

private   string  Formal( string  first,  string  surname)
{
    
return  first  +   "   "   +  surname;
}

 

返回FirstName+空格+LastName 

(二)With

流暢式的指望和驗證語法。什麼是流暢式?先看例子:

[Test]
public   void  TestFluent()
{
    MockRepository mocks 
=   new  MockRepository();
    var customer 
=  mocks.DynamicMock < ICustomer > ();

    
string  strTemp = string .Empty; 

    With.Mocks(mocks)
        .Expecting(
          
delegate
          {
             Expect.Call(customer.ShowTitle(
"" )).Return( " with 語句 " );
          })
        .Verify(
         
delegate
          {
             strTemp 
=  customer.ShowTitle( "" );
          });

    Assert.AreEqual(
" with 語句 " , strTemp);
}

 

這就是所謂的流暢式。經過匿名委託來實現。若是在匿名委託中完成則會隱匿調用ReplayAll()mocks.VerifyAll()

若是要啓用次序,則可以使用:ExpectingInSameOrder,例如:

[Test]
public   void  TestFluent()
{
    MockRepository mocks 
=   new  MockRepository();
    var customer 
=  mocks.DynamicMock < ICustomer > ();
    
string  strTemp = string .Empty;
    With.Mocks(mocks).ExpectingInSameOrder(
        
delegate
        {
           Expect.Call(customer.ShowTitle(
"" )).Return( " with 語句 " );
           Expect.Call(customer.Unid).Return(
1 );
        })
       .Verify(
       
delegate
       {
          strTemp 
=  customer.ShowTitle( "" );
          
int  i  =  customer.Unid;
       });

    Assert.AreEqual(
" with 語句 " , strTemp);
}

 

With語句的隱式使用

With能夠隱式的建立Mock實例,並自動調用VerifyAll方法。

[Test]
public   void  TestWithMocker()
{
    With.Mocks(
        
delegate
        {
          var customer 
=  Mocker.Current.DynamicMock < ICustomer > ();
          Expect.Call(customer.ShowTitle(
"" )).Return( " with 語句 " );
          Mocker.Current.ReplayAll();

          Assert.AreEqual(
" with 語句 " , customer.ShowTitle( "" ));
        });
}

 

這裏纔看出With確實很流暢。

下邊說一下由顯式建立Mock實例來代替隱式建立:

[Test]
public   void  TestWithMockerr()
{
    MockRepository mocks 
=   new  MockRepository();
    With.Mocks(mocks,
       
delegate
       {
          var customer 
=  Mocker.Current.DynamicMock < ICustomer > ();
          Expect.Call(customer.ShowTitle(
"" )).Return( " with 語句 " );

          Mocker.Current.ReplayAll();

          Assert.AreEqual(
" with 語句 " , customer.ShowTitle( "" ));
       });
}

 

沒多大區別。在使用Mocker.Current時,不能在嵌套中使用,由於這是個全局的,而With.Mocks會重寫Mocker.Current

(三)Record-PlayBack

Rhinomock支持一種經過Using語句來進行錄製回放的方式。

[Test]
public   void  TestRecordPlayback()
{
    MockRepository mocks 
=   new  MockRepository();
    var customer 
=  mocks.DynamicMock < ICustomer > ();

    
using  (mocks.Record())
    {
        Expect.Call(customer.ShowTitle(
"" )).Return( " 錄製回放 " );
    }

    
using  (mocks.Playback())
    {
        Assert.AreEqual(
" 錄製回放 " , customer.ShowTitle( "" ));
    }
}

 

 

評論: 0 查看評論 發表評論

程序員找工做,就在博客園

最新新聞:
· 電子商務網站之信任度(2010-10-09 17:02)
· 馬雲:管理的核心在於「抓住人性的本真」(2010-10-09 16:52)
· 另外一 Windows Phone Live 主頁截圖現身 Windows Phone 7 視頻(2010-10-09 16:38)
· 谷歌首名員工:公司成功歸結於運氣不錯(2010-10-09 16:32)
· 神奇小子Geohot帶着「limera1n」迴歸(2010-10-09 16:29)

編輯推薦:遠離.NET

網站導航:博客園首頁  我的主頁  新聞  閃存  小組  博問  社區  知識庫

相關文章
相關標籤/搜索