[英]Unit Testing of a static factory method containing logic
在開始我的問題之前,我想指出的是,我知道在堆棧溢出中有很多類似的問題。 不幸的是,這些問題都沒有幫助我在具體情況下找到好的解決方案。
問題:
我想為包含邏輯的靜態工廠方法編寫單元測試。 我正在尋找一種對該方法進行單元測試的方法,即使它是靜態的。 如果這不可能,那么也許有人可以為我正在測試的班級指出更好的設計。 我也考慮過使用IoC,但是在考慮單元測試時看不到優勢。
編碼:
public class Db
{
private XmlMapping mapping;
public static Db<T> Create()
{
var mapping = XmlMapping.Create(typeOf(T).Name);
return new Db(mapping);
}
private Db(XmlMapping mapping)
{
this.mapping = mapping;
}
}
public class XmlMapping //class under test
{
public static XmlMapping Create(string filename) //method under test
{
try
{
ValidateFilename(filename);
//deserialize xml to object of type XmlMapping
var result = Deserialize(filename);
if (result.IsInValid())
throw Exception()
return result;
}
catch (Exception)
{
throw new DbException();
}
}
}
我要進行單元測試的Create方法在XmlMapping類中。 此方法序列化xml文件並生成XmlMapping類型的對象。 我嘗試為序列化部分編寫存根。 但是不想用構造函數中的Mapping類調用我的數據庫工廠(構造函數注入)。
編輯:
我的數據庫工廠是通用的。 通用類型用於確定應該大聲顯示哪個xml文件,即: typeOf(T)= Customer-> XmlMapping-File = Customer.xml
解決方法(謝謝傑夫!):
public class XmlMapping : IMapping //class under test
{
internal static Func<Type, IMapping> DeserializeHandler { get; set; }
static XmlMapping()
{
DeserializeHandler = DeserializeMappingFor;
}
public static IMapping Create(Type type)
{
try
{
var mapping = DeserializeHandler(type);
if (!mapping.IsValid())
throw new InvalidMappingException();
return mapping;
}
catch (Exception ex)
{
throw new DataException("Failed to load mapping configuration from xml file.", ex);
}
}
internal XmlMapping(IMapping mapping)
{
this.Query = mapping.Query;
this.Table = mapping.Table;
this.Entity = mapping.Entity;
this.PropertyFieldCollection = mapping.PropertyFieldCollection;
}
private XmlMapping() { }
}
[TestClass]
public class MappingTests //testing class
{
[TestMethod]
public void Create_ValidDeserialization_ReturnsObjectInstance()
{
XmlMapping.DeserializeHandler = MakeFakeHandlerFor(MakeMappingStub());
var result = XmlMapping.Create(typeof(ActivityDto));
Assert.IsInstanceOfType(result, typeof(XmlMapping));
}
}
我將使用偽造的動作處理程序來幫助驗證反序列化調用的內容。 讓我們添加一個Func委托屬性,並將其默認設置為您的序列化方法。 您的XmlMapping類和測試將類似於:
public class XmlMapping //class under test
{
static XmlMapping()
{
// Default the handler to the normal call to Deserialize
DeserializeHandler = Deserialize;
}
public static XmlMapping Create(string filename) //method under test
{
//deserialize xml to object of type XmlMapping
//preudocode:
var result = DeserializeHandler(string.Format("{0}.xml",filename));
//...
return result;
}
// Abstract indirection function to allow you to swap out Deserialize implementations
internal static Func<string, XmlMapping> DeserializeHandler { get; set; }
private static XmlMapping Deserialize(string fileName)
{
return new XmlMapping();
}
}
public class CreateTests {
public void CallingDeserializeProperly()
{
// Arrange
var called = false;
Func<string, XmlMapping> fakeHandler = (string f) =>
{
called = true; // do your test of the input and put your result here
return new XmlMapping();
};
// Act
XmlMapping.DeserializeHandler = fakeHandler;
var m = XmlMapping.Create("test");
// Assert
Assert.IsTrue(called);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.