选项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,因为每次域方法创建另一个域实体时,我不必测试创建的实体的属性(在工厂测试中只测试一次)。
有人有更好的解决方案吗?
更新:
来自@user1494736 的回答:“我认为,如果您正在测试 Parent,您还应该测试 Child 构造函数”。您可能有另一种Parent
创建方法Child
,并且在其测试中您需要Child
再次测试属性。一般来说,我不想在Child
每次Parent
方法调用它时都测试构造函数的结果。让我们假设Child
构造函数根据构造函数参数进行一些复杂的计算。您将Child
仅对构造函数进行几次测试,以测试各种组合和结果。现在,如果您要在测试中测试Child
构造函数Parent
,并且您将修改Child
构造函数实现,这些Parent
测试会开始失败(我不喜欢的事情,也是我更喜欢选项 2 的主要原因,即使我也有一些保留意见)