質問を始める前に、スタック オーバーフローに関する同様の質問がたくさんあることを認識していることを指摘しておきます。残念ながら、これらの質問のどれも、私の具体的なシナリオで適切な解決策を見つけるのに役立ちませんでした.
問題:
ロジックを含む静的ファクトリ メソッドの単体テストを作成したいと考えています。静的であっても、このメソッドを単体テストする方法を探しています。それが不可能な場合は、テスト中のクラスのより良い設計を誰かが指摘できるかもしれません。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 です。
解決策 (Thx to Jeff!):
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));
}
}