我在一个名为 Tools.Client 的项目中定义了一个 Person 类,它是一个 Web 服务 API 的包装器。Person 是使用服务返回的 XML 构造的。
public class Person
{
internal Person(XElement personElement)
{
this.FirstName = personElement.Element("first_name").Value;
this.LastName = personElement.Element("last_name").Value;
this.Jobs = new List<Job>();
foreach (var jobElement in personElement.Elements("jobs"))
{
this.Jobs.Add(new Job(jobElement));
}
}
public string FirstName {get; private set;}
public string LastName {get; private set;}
public ICollection<Job> {get; private set;}
}
我在一个名为 Tools.Analysis 的单独项目中有另一个名为 Analyzer 的类,它包含针对从 API 客户端检索到的数据运行的分析逻辑。
private readonly ICollection<Person> _people;
public Analyzer(ICollection<Person> people)
{
_people = people;
}
public AnalysisResult Analyze()
{
var result = new AnalysisResult();
foreach (var person in _people)
{
// do some analysis, store data in the result
}
return result;
}
我想为 Analyzer 类的 Analyze 方法编写单元测试,但我不确定如何解决以下问题:
Person 有一个带有 XElement 参数的内部构造方法。我不想在我的单元测试中创建手动 XElement 对象。
Person 有私人设置器(我认为应该如此,我不希望 Tools.Client 的用户更改从 API 返回的数据)。对具有类似结构的 Job 的额外依赖加剧了这个问题。
我可以想到一些解决方案,但不知道随着时间的推移哪个是最可维护的:
- 创建 IPerson 和 IJob 接口并使用这些接口的模拟或简单测试实现。
- 公开公共设置器以便于测试(同样,我不太喜欢这样)。我想我也可以使用带有 InternalsVisibleTo 属性的内部设置器(不像公共那么糟糕,但仍然不是我想要的)。
- 将 XML 解析移到构造函数之外,并让构造函数获取参数 firstName、lastName、jobs。构造函数仍然可以是内部的,我只需要在我的程序集中使用 InternalsVisibleTo 属性。