我遇到了我的工作中的一類,看起來像這樣:使用例如創建模擬和匿名對象的混合Moq和AutoFixture?
public class MyObject
{
public int? A {get; set;}
public int? B {get; set;}
public int? C {get; set;}
public virtual int? GetSomeValue()
{
//simplified behavior:
return A ?? B ?? C;
}
}
的問題是,我有一些代碼,訪問A,B和C,並調用GetSomeValue()方法(現在,我會說這不是一個好設計,但有時候我的雙手被捆綁;-))。我想創建一個這個對象的模擬,同時,A,B和C設置爲一些值。所以,當我使用起訂量爲這樣:
var m = new Mock<MyObject>() { DefaultValue = DefaultValue.Mock };
讓我安裝上GetSomeValue結果()方法,但所有屬性都設置爲null(使用安裝程序設置所有的人()是相當繁瑣的,因爲真實對象是一個令人討厭的數據對象,並且具有比上述簡化示例更多的屬性)。
因此在另一方面,使用AutoFixture這樣的:
var fixture = new Fixture();
var anyMyObject = fixture.CreateAnonymous<MyObject>();
令我無以STUP到GetSomeValue()的調用方法的能力。
是否有任何方法將這兩者結合起來,具有匿名值和設置調用結果的能力?
編輯
基於nemesv的回答,我得出了以下的實用方法(希望我這樣做是正確):
public static Mock<T> AnonymousMock<T>() where T : class
{
var mock = new Mock<T>();
fixture.Customize<T>(c => c.FromFactory(() => mock.Object));
fixture.CreateAnonymous<T>();
fixture.Customizations.RemoveAt(0);
return mock;
}
這是一個很好的解決方案,特別是因爲它涵蓋了嵌套類型,但是,它是更普遍的嵌套類型,有沒有什麼辦法來擺脫部分:T == typeof運算(的MyObject)| | t == typeof(MyParent)? 我想到的邏輯是這樣的:「如果混合的嵌套類型是可嘲弄的,使其成爲一個混合,否則使它成爲一個匿名值」。 – 2012-02-19 12:30:15
是的,只需要用更一般的東西來替代謂詞即可。 – 2012-02-19 12:50:24
謝謝!我嘗試使用(t!= null &&!!..IsPrimitive &&(t.GetConstructors(BindingFlags.Public).Length!= 0 || t.GetConstructor(Type.EmptyTypes)!= null))的謂詞上班!你能看到這裏有什麼遺漏嗎?我會盡量給它一點測試,並嘗試讓你知道是否有任何事情發生。 – 2012-02-19 20:33:39