2010-06-04 153 views
21

我有這樣一組構造函數:使用Moq來模擬構造函數?

public BusinessObjectContext() 
     : this(CloudStorageAccount.FromConfigurationSetting("DataConnectionString").TableEndpoint.ToString(), 
       CloudStorageAccount.FromConfigurationSetting("DataConnectionString").Credentials) {} 

public BusinessObjectContext(string dataConnectionString) 
     : this(CloudStorageAccount.Parse(dataConnectionString).TableEndpoint.ToString(), 
       CloudStorageAccount.Parse(dataConnectionString).Credentials) { } 

public BusinessObjectContext(String baseAddress, StorageCredentials credentials) 
     : base(baseAddress, credentials) { } 

然而,當測試/懲戒我需要的對象,而無需任何連接字符串參數。我怎麼能這樣做 - 最好在Moq?

這可能嗎?

回答

17

聽起來好像你有代碼味道 - constructor is doing too much work。該文章包含針對這些場景的一組修復程序。基本上答案是只有在構造函數中執行賦值,不執行業務邏輯。

+0

Hrrm。我在這個概念中看到了這個觀點。另一方面,我想屏蔽對象GenericBusinessObject的用戶,從而思考數據源上下文。 如果我遵循你的論點,那麼GenericBusinessObject的用戶必須考慮它。這是不太吸引人的。也許沒有別的辦法,但是有些事情讓我猶豫不決。 – 2010-06-10 13:56:40

+1

建立工廠或使用IOC Conatainer來消除用戶擔心數據上下文的這種需求。 – Finglas 2010-06-13 10:07:55

26
var myMockBOC = new Mock<BusinessObjectContext>(null, null); 

這將通過空值爲您的兩個參數。

另一種方法是創建一個僅供測試使用的內部構造函數,並使用InternalsVisibleTo來允許測試程序集使用它。不幸的是,這有一個很大的缺點,如果你簽署你的程序集,Moq is unable to use the constructor。這應該在Moq的4.0版本中解決。

+6

內部構造函數的缺點是,現在您正在編寫代碼來支持您的單元測試。 – 2010-11-15 20:48:53

+2

我會爭辯說,這是可以接受的,當有一個有目的的要求* public * API不可注射。如果你的構造函數不是簡單的,並且包含商業邏輯 - 那麼,正如俗話所說,你會遇到兩個問題...... – womp 2010-11-25 17:49:25

+0

非常簡單的解決方案!幫助了我很多! – 2013-06-05 17:00:10