0

我似乎找不到太多关于这方面的信息,所以我想我会在这里提出来。我经常发现自己遇到的问题之一是在处理列表时对单个对象的创建进行单元测试。例如,我有一个方法签名,例如IEnumerable<Output> Process(IEnumerable<Input> inputs). 当对单个输入进行单元测试时,我会创建一个输入列表并简单地调用First()结果并确保它是我期望的。这将导致诸如:

public class BatchCreator
{
    public IEnumerable<Output> Create(IEnumerable<Input> inputs)
    {
        foreach (var input in inputs)
        {
            Console.WriteLine("Creating Output...");
            yield return new Output();
        }
    }
}

我目前的想法是,也许一个类应该负责创建对象,而另一个类负责编排我的输入列表。请参见下面的示例。

public interface ICreator<in TInput, out TReturn>
{
    TReturn Create(TInput input);
}

public class SingleCreator : ICreator<Input, Output>
{
    public Output Create(Input input)
    {
        Console.WriteLine("Creating Output...");
        return new Output();
    }
}

public class CompositeCreator : ICreator<IEnumerable<Input>, IEnumerable<Output>>
{
    private readonly ICreator<Input, Output> _singleCreator;

    public CompositeCreator(ICreator<Input, Output> singleCreator)
    {
        _singleCreator = singleCreator;
    }

    public IEnumerable<Output> Create(IEnumerable<Input> inputs)
    {
        return inputs.Select(input => _singleCreator.Create(input));
    }
}

通过上面发布的内容,我可以轻松测试我是否能够创建一个Output给定的Input. 请注意,除了 from 之外,我不需要调用SingleCreator代码库中的任何其他位置CompositeCreator。创建ICreator还可以让我在需要执行类似任务的其他时间重复使用它,我目前在当前项目中执行 2-3 次

有没有人有这方面的经验可以提供一些启示?我只是想太多了吗?非常感谢您的建议。

4

2 回答 2

2

一般来说,你的推理本质上没有错。或多或少这就是解决问题的方法。

但是,您CompositeCreator实际上并不是复合的,因为它恰好使用一种“创建方法”。

很难说更多,因为我们不了解您的项目内部情况,但如果它很好地集成到您的用例中,那就没问题了。我会尝试的只是留下来ICreator<Tin, Tout>并制作一个扩展方法IEnumerable<Tout> CreateMany(this IEnumerable<Tin> c)来处理集合。您可以轻松、独立地测试两者(伪造ICreator并检查是否处理了输入集合)。这样你就可以摆脱ICreator<IEnumerable, ...>,这通常是好的,因为作为一个整体对集合进行操作和对单个项目进行操作通常不能很好地结合在一起。

于 2013-03-19T13:57:14.887 回答
1

我不完全确定你为什么需要 IEnumerable 输入/输出选项,复合创建者,除非它不仅仅是一个集合,因为这是 LINQ 解决的问题,看起来像:

var singleCreator = new SingleCreator();
var outputs = InputEnumerable.Select(singleCreator.Create);

我认为这是主观的,并且取决于您传递的类的复杂性 - 如果它不仅仅是一个 IEnumerable ,那么拥有某种多重创建者是值得的,它可能需要也可能不需要是一个类。

于 2013-03-19T14:00:54.697 回答