gpt4 book ai didi

c# - 我应该如何检查工厂在单元测试中创建的对象图

转载 作者:行者123 更新时间:2023-11-30 18:03:56 25 4
gpt4 key购买 nike

我有一些类似于下面的代码:

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 实例的事实——而不是具体实现是什么。尽管如此,我还是想测试一下工厂类是否做了它应该做的事情——构建一个具体的对象图。

我是否应该编写一些测试来调用创建方法并检查返回对象的属性? This question似乎表明是这样,但是如果我需要检查多层类和属性以验证工厂创建的对象图,这是否仍然适用?这不会导致测试代码如:

var created = objectUnderTest.Create(MyEnum.A);
var itemBuilder = (created.Items as MyLazyItemCollection).Builder;
Assert.IsInstanceOfType(itemBuilder, typeof(MyRemoteItemBuilder));

我不是特别喜欢 created.Items 的沮丧,但在我看来,这是断言工厂创建了 MyLazyItemCollection 的唯一方法正确,因为并非每个 IMyItemCollection 都可以预期具有 builder 属性......这只是图表的第二层。我可能需要进一步深入了解 MyRemoteItemBuilder 的依赖关系,看看它们是否已正确创建:

var service = ((created.Items as MyLazyItemCollection)
.Builder as MyRemoteItemBuilder).Service;
Assert.IsInstanceOfType(service, typeof(MyService));

我应该以这种方式测试我的工厂,接受难看的嵌套向下转型 - 毕竟这是测试代码 - 或者我应该将 IMyItemCollection 构造拉到另一个工厂并将其作为依赖项添加到我的 MyConcreteClassFactory(所以我可以从测试代码中注入(inject)它并断言 created.Items 的值是由我的模拟工厂创建的实例)。我预计后者会很快导致工厂-工厂和工厂-工厂-工厂的爆炸式增长。毕竟,MyConcreteClassFactory 的用户不需要为她必须提供特定子工厂这一事实而烦恼,她应该……吗?

最佳答案

当然要看需求,但我的回答是否定的。

你永远不应该以“测试实现(或细节)”的方式设计你的测试,这在开始时可能工作得很好,但过了一段时间你就会遇到麻烦。实现变化非常快,每次更改都必须纠正许多测试用例。

相反,您必须“测试行为”。它基本上意味着您抽象了所有细节(具体类),并且您测试用例来测试一些有值(value)的场景,而不是细节。

我的选择是创建“测试实现”用例,然后再进行 TDD。但后来他们必须用“测试行为”案例进行重构。

如果您不仅要论证测试用例的数量,还要论证构建真实安全网的质量,这一点非常重要。

关于c# - 我应该如何检查工厂在单元测试中创建的对象图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6689884/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com