オプション1.ParentTest.CreateChild()
本質的にコンストラクターもテストChild
しています(これは好きではありません)。
public class Parent
{
public Child Child { get; private set; }
public void CreateChild(int param1, string param2)
{
Child = new Child(param1, param2);
}
}
public class Child
{
public int Param1 { get; private set; }
public string Param2 { get; private set; }
public Child(int param1, string param2)
{
Param1 = param1;
Param2 = param2;
}
}
[TestFixture]
public class ParentTest
{
[Test]
public void CreateChild()
{
const int param1 = 23;
const string param2 = "param2";
var parent = new Parent();
parent.CreateChild(param1, param2);
Assert.That(parent.Child, Is.Not.Null);
Assert.That(parent.Child.Param1, Is.EqualTo(param1));
Assert.That(parent.Child.Param2, Is.EqualTo(param2));
}
}
[TestFixture]
public class ChildTest
{
[Test]
public void Create()
{
const int param1 = 23;
const string param2 = "param2";
var child = new Child(param1, param2);
Assert.That(child.Param1, Is.EqualTo(param1));
Assert.That(child.Param2, Is.EqualTo(param2));
}
}
オプション 2. ファクトリ サービスを使用してChild
インスタンスを作成します。ここで、サービスをドメイン メソッドのパラメーターとして渡すという考えについては、あまりよくわかりません。
public class Parent
{
public Child Child { get; private set; }
public void CreateChild(int param1, string param2, IChildFactory childFactory)
{
Child = childFactory.Create(param1, param2);
}
}
public class Child
{
public int Param1 { get; private set; }
public string Param2 { get; private set; }
protected Child() {} // to be able to generate stub
public Child(int param1, string param2)
{
Param1 = param1;
Param2 = param2;
}
}
public interface IChildFactory
{
Child Create(int param1, string param2);
}
public class ChildFactory : IChildFactory
{
public Child Create(int param1, string param2)
{
return new Child(param1, param2);
}
}
[TestFixture]
public class ParentTest
{
[Test]
public void CreateChild()
{
const int param1 = 23;
const string param2 = "param2";
var child = MockRepository.GenerateStub<Child>();
var childFactory = MockRepository.GenerateStub<IChildFactory>();
childFactory.Stub(x => x.Create(param1, param2)).Return(child);
var parent = new Parent();
parent.CreateChild(param1, param2, childFactory);
Assert.That(parent.Child, Is.SameAs(child));
}
}
[TestFixture]
public class ChildTest
{
// empty as contructor is tested in ChildFactoryTest
}
[TestFixture]
public class ChildFactoryTest
{
[Test]
public void Create()
{
const int param1 = 23;
const string param2 = "param2";
var childFactory = new ChildFactory();
var child = childFactory.Create(param1, param2);
Assert.That(child.Param1, Is.EqualTo(param1));
Assert.That(child.Param2, Is.EqualTo(param2));
}
}
ドメインメソッドが別のドメインエンティティを作成するたびに、作成されたエンティティのプロパティをテストする必要がないため、実際にはオプション 2 を好みます (これらはファクトリテストで 1 回だけテストされます)。
誰もがより良い解決策を持っていますか?
更新:
@ user1494736 の回答から: 「親をテストしている場合は、子コンストラクターもテストする必要があると思います」 . Parent
を作成する別の方法がChild
あり、そのテストでChild
プロパティを再度テストする必要がある場合があります。一般に、メソッドが呼び出すChild
たびにコンストラクターの結果をテストしたくありません。コンストラクターがコンストラクターParent
のパラメーターから複雑な計算を行うとします。さまざまな組み合わせと結果をテストするためだけに、コンストラクターだけでChild
いくつかのテストが必要になります。Child
ここで、テストChild
でコンストラクターをテストし、コンストラクターの実装Parent
を変更する場合、これらはChild
Parent
テストは失敗し始めます(私が好きではないことであり、オプション2を好む主な理由でもありますが、いくつかの予約があります)