2017-09-27 61 views
0

在C#下有一個很好的工具,假部分測試實現複雜的接口(服務,存儲庫等)?最好的接口模擬/假的部分實現

我目前使用的模擬框架(RhinoMocks)太慢,太難以處理這個目的。

先決條件:

  • 沒有顯著的性能損失,相比於真正的實現(批量測試)
  • 實現與基本的邏輯和數據(例如:字典,而不是數據庫表)
  • 無需更換測試,當界面改變時。

全面推行例如:

public interface IMyInterface 
{ 
    int PropertyA { get; set; } 
    int PropertyB { get; set; } 
    void DoSomethingWithX(int x); 
    int GetValueOfY(); 
} 

public class FakeImplementation : IMyInterface 
{ 
    private int _valueOfYCalls = 0; 

    public int PropertyA { get; set; } 
    public int PropertyB { get; set; } 
    public void DoSomethingWithX(int x) 
    { } 

    public int GetValueOfY() 
    { 
     return _valueOfYCalls++; 
    } 
} 

計數器只是模擬了基本的邏輯。

問題是,如果接口得到一個新的方法,如SetSomeZ(int z),測試將不會建立/運行了,沒有明確的改變。

有沒有一個假的/模擬的框架,使用基本的實現,但通過虛擬/覆蓋或包裝自動添加成員?

像這樣的:

[ImplementsInterface(nameof(IMyInterface))] 
public class FakeImplementationBase 
{ 
    private int _valueOfYCalls = 0; 

    [ImplementsMember(nameof(IMyInterface.GetValueOfY))] 
    public virtual int GetValueOfY() 
    { 
     return _valueOfYCalls++; 
    } 
} 

工具/框架應​​在運行時生成全面實現類型,類似於嘲笑/存根,但使用的基本實現,只需添加缺少的接口部分。

這不應該是真正的單元測試,而是爲了更復雜的目的。它也是具有豐富接口和類的傳統軟件,並不太多關於「單一責任」。

回答

0

Moq正是你想要的。

public interface IFoo { 
    int MethodA(int a); 
    void MethodB(long b); 
    void MethodC(string c); 
    ... 
} 

var MoqFoo = new Mock<IFoo>(); 
MoqFoo.Setup(m => m.MethodA(It.Is(a => a > 0)).Returns<int>(a => a + 1); 
MoqFoo.Setup(m => m.MethodC(It.IsAny<string>()).Callback<string>(c => Debug.Write(c)); 

請注意我們怎麼沒有爲MethodB做.Setup()?當你聲明它時,所有的方法和屬性都會得到虛擬方法/屬性,.Setup()將會指定你自己定製的方法和屬性。所以如果你的接口有10個方法,但你只想測試MethodD(),你只需要爲它編寫代碼。

http://www.developerhandbook.com/unit-testing/writing-unit-tests-with-nunit-and-moq/

+0

謝謝,Moq的表現如何? RhinoMocks有類似的語法,但比實際的類慢得多(只要它們只在內存中)。我想避免RhinoMocks中'.Setup(...)'或'.Stub()'的相當複雜的語法。我期望框架在運行時創建一個新類型,它像一個普通類一樣實例化,只進行一次反射,然後像編碼類那樣執行性能。 –