C# 我应该如何在单元测试中检查工厂创建的对象图
我有一些类似于以下的代码:C# 我应该如何在单元测试中检查工厂创建的对象图,c#,unit-testing,tdd,C#,Unit Testing,Tdd,我有一些类似于以下的代码: public interface IMyClass { MyEnum Value { get; } IMyItemCollection Items { get; } } public class MyConcreteClassFactory : MyClassFactoryBase { public override IMyClass Create(MyEnum value) { var itemBuilder = n
public interface IMyClass
{
MyEnum Value { get; }
IMyItemCollection Items { get; }
}
public class MyConcreteClassFactory : MyClassFactoryBase
{
public override IMyClass Create(MyEnum value)
{
var itemBuilder = new MyRemoteItemBuilder();
var itemCollection = new MyLazyItemCollection(itemBuilder)
return new MyClass(value, itemCollection);
}
}
“真正的”代码应该只关心工厂返回IMyClass实例这一事实,而不是具体实现是什么。尽管如此,我还是想测试factory类是否完成了它应该做的事情—构建一个具体的对象图
我是否应该编写一些调用create方法并检查返回对象属性的测试?看起来是这样的,但是如果我需要检查多个类和属性层来验证工厂创建的对象图,这是否仍然适用?这不会导致测试代码,例如:
var created = objectUnderTest.Create(MyEnum.A);
var itemBuilder = (created.Items as MyLazyItemCollection).Builder;
Assert.IsInstanceOfType(itemBuilder, typeof(MyRemoteItemBuilder));
我并不特别喜欢created.Items
,但在我看来,这将是断言工厂正确创建了MyLazyItemCollection
的唯一方法,因为并非每个IMyItemCollection
都有生成器属性。。。这只是图表的第二层。我可能需要进一步挖掘MyRemoteItemBuilder
的依赖关系,以查看它们是否正确创建:
var service = ((created.Items as MyLazyItemCollection)
.Builder as MyRemoteItemBuilder).Service;
Assert.IsInstanceOfType(service, typeof(MyService));
我应该以这种方式测试我的工厂,接受难看的嵌套降级-毕竟这是测试代码-还是应该将
IMyItemCollection
构造拉入另一个工厂,并将其作为依赖项添加到我的MyConcreteClassFactory
(因此我可以从测试代码中注入它,并断言created.Items
的值是我的模拟工厂创建的实例)。我预计后者将很快导致工厂和工厂的爆炸。毕竟,MyConcreteClassFactory
的用户不必为她必须提供特定的子工厂而烦恼,是吗?这当然取决于需要,但我的答案是否定的
您永远不应该以“测试实现(或细节)”的方式来设计您的测试,这种方式在一开始可能会非常好地工作,但过一段时间您就会遇到麻烦。实现的变化非常快,每次更改都会迫使您纠正许多测试用例
相反,您必须“测试行为”。它基本上意味着您对所有细节(具体类)进行抽象,并测试测试一些有价值的场景的案例,而不是细节
我的选择是创建“测试实现”案例,然后我会使用TDD。但稍后它们必须用“测试行为”案例进行重构
这一点非常重要,如果你不仅要说明测试用例的数量,还要说明构建真正安全网的质量。这是否意味着你根本不会为这个工厂编写单元测试?工厂所做的只是具体类的布线。最终,我将有一套集成测试,如果布线错误,这些测试将失败……是的,可能会失败ly不会按照TDD的格言“在编写测试中的方法之前编写每个测试”,这也意味着我不应该在最后一刻才真正编写我的工厂——因为在进行集成测试之前,我并不真正需要我的具体工厂。我想这是有意义的…+1这是一个很好的问题。