2011-03-10 20 views
26

是否有可能從沒有提供無參數構造函數的類創建模擬並且不將任何參數傳遞給構造函數?也許動態創建IL?在C#/ .NET中沒有無參數構造函數的模仿對象

背景是我不想定義僅用於測試的接口。解決方法是爲測試提供無參數的構造函數。

+3

爲什麼你不希望創建接口?您可以輕鬆地從類中提取界面,然後在其他地方使用界面。在代碼中創建更少的依賴性和更好的抽象。 – 2011-03-10 16:46:36

+0

從Moq用於創建Mocks的用法來說,您需要使這些方法變爲虛擬。似乎在這種情況下,界面通常更好。不確定其他Mocking框架。 – 2011-03-10 16:50:37

+3

理想情況下,應該在整個代碼中使用接口;與具體的實現相比,因此將「僅爲測試創建接口」作爲評論的一個爭論點。 – 2011-03-10 16:51:43

回答

38

當然可以。在這個例子中,我將使用Moq,一個非常棒的嘲笑庫。

例子:

public class MyObject 
{ 
    public MyObject(object A, object B, object C) 
    { 
      // Assign your dependencies to whatever 
    } 
} 

Mock<MyObject> mockObject = new Mock<MyObject>(); 
Mock<MyObject> mockObject = new Mock<MyObject>(null, null, null); // Pass Nulls to specific constructor arguments, or 0 if int, etc 

在許多情況下,雖然,我指定Mock對象作爲參數,所以我可以測試的依賴關係:

Mock<Something> x = new Mock<Something>(); 
MyObject mockObject = new MyObject(x.Object); 

x.Setup(d => d.DoSomething()).Returns(new SomethingElse()); 

etc 
+0

同意。 Moq很棒。他們在一個網頁上有完整的操作指南。你不能那麼容易使用/學習。 – 2011-03-10 16:59:00

+2

當構造函數需要非空值(帶有代碼合同或例外)時它工作嗎? – deamon 2011-03-10 16:59:24

+0

例如,如果你有一個整數,你可以傳遞一個0.如果它是一個字符串,Null,string.Empty等等,你可以使用默認的(T),其中T:你的參數類型和一切正常精細。如果你正在創建一個模擬對象,標記爲虛擬的方法/屬性將永遠不會被執行。你可以控制他們所做的事(通過回調)或者他們返回(通過Return方法)模擬對象。 – Tejs 2011-03-10 18:41:29

1

相信您提供的接口僅用於測試是錯誤的。接口可以提供抽象並減弱代碼的不同層次之間的耦合,使它們在不同的上下文中更具可重用性。

這就是說,答案將取決於你正在使用的模擬框架。例如與犀牛嘲笑你可以有:

public class Foo 
{ 
    public Foo(string bar) 
    { } 

    public virtual int SomeMethod() 
    { 
     return 5; 
    } 
} 

然後:

var fooMock = MockRepository.GeneratePartialMock<Foo>("abc"); 
fooMock.Expect(x => x.SomeMethod()).Return(10); 
+1

取決於你的觀點:確實,開發者應該編寫接口來減弱耦合。假如,QA不希望只爲測試目的「改進」功能代碼,如果他可以跳過 – PPC 2012-07-12 15:40:52

相關問題