2012-08-07 35 views
2

我是使用Mocking框架來模擬對象進行單元測試的新手。我目前正在使用Rhino Mocks,我認爲它會有一種方法來做我沒有找到它的方法。這裏是一個LinqPad程序(只需複製並粘貼在C#程序查詢,都可以正常運行),它顯示我想要做的事:如何模擬一個類的單一方法?

public interface MyTest{ 
    int A(int i); 
    string B(int i); 
} 

/// This is an actual class that is a black box to me. 
public class ActualClass : MyTest { 
    public int A(int i){ 
     // Does some work 
     return ++i; 
    } 

    public string B(int i){ 
     return A(i).ToString(); 
    } 
} 

/// I'd like to create a mocked class that uses an instance of the actual class 
/// to provide all of the implementations for the interface except for a single method 
/// where I can check the parameter values, and provide my own return value, 
/// or just call the actual class 
public class MockedClass : MyTest { 

    private ActualClass _actual; 
    public MockedClass(ActualClass actual){ 
     _actual = actual; 
    } 
    public int A(int i){ 
     if(i == 1){ 
      return 10; 
     }else{ 
      return _actual.A(i); 
     } 
    } 

    public string B(int i){ 
     return _actual.B(i); 
    } 
} 

void Main() 
{ 
    var mock = new MockedClass(new ActualClass()); 
    mock.A(0).Dump(); 
    mock.A(1).Dump(); 
    mock.A(2).Dump(); 
    mock.B(0).Dump(); 
    mock.B(1).Dump(); 
    mock.B(2).Dump(); 
} 

結果:

1 
10 
3 
1 
2 
3 

我該如何嘲笑單元測試。我需要某種依賴注入器嗎?

+0

你的意思是如何使用Rhino模擬創建類來替換MockedClass? – 2012-08-07 17:19:03

+0

@Congong是的。在我的實際課程中有很多方法,我不想全部實施它們,即使它是鍋爐板代碼。 – Daryl 2012-08-07 17:20:04

+0

爲什麼你不嘗試繼承MockedClass:AactualClass,那麼你不需要添加無用的方法? – 2012-08-07 17:28:28

回答

1

是的,您可以根據傳入的參數更改模擬對象的返回值。我不會採用混合真實依賴和模擬依賴的方法 - 對於真實中的錯誤有太多機會依賴性蔓延到您的測試。

這裏是你可以在你的MyTest的接口上使用檢查嘲笑方法的輸入參數,並相應設置一個返回值的例子:

var mock = MockRepository.GenerateStub<MyTest>(); 
mock.Stub(m => m.A(Arg<int>.Is.Anything)) 
    .Return(99) 
    .WhenCalled(mi => 
        { 
         var arg = Convert.ToInt32(mi.Arguments[0]); 
         switch (arg) 
         { 
          case 0: 
           mi.ReturnValue = 10; 
           break; 
          case 1: 
           mi.ReturnValue = 20; 
           break; 
          case 2: 
           mi.ReturnValue = 30; 
           break; 
          default: 
           mi.ReturnValue = -1; 
           break; 
         } 
        }); 

注意,「返回(99)」是必要的,因爲當你存根一個返回值的方法,Rhino.Mocks 要求你要麼定義一個要拋出的異常,要麼定義一個返回值。儘管我們沒有使用返回值(因爲我們在WhenCalled處理程序中提供了自己的內部函數),但它仍然必須定義或Rhino.Mocks在第一次調用存根時會拋出異常。