我有一个方法,它调用.NET XDocument.Load()方法从URL加载xml数据。我想让我的班级单元可以测试。
那么如何使该调用可模拟/单元可测试?
private void ProcessData(string url)
{
// todo: make this mockable
var xDocument = XDocument.Load(url);
// the rest of the code
}
我使用的一个解决方案是将xmlUrlLoader注入到clas中,如下所示:
private readonly Func<string, XDocument> _xmlUrlLoader;
public MyConstructor(Func<string,XDocument> xmlUrlLoader)
{
_xmlUrlLoader = xmlUrlLoader;
}
private void ProcessData(string url)
{
// todo: make this mockable
var xDocument = this._xmlUrlLoader(url);
// the rest of the code
}
还有更好的方法吗?
答案 0 :(得分:3)
我同意注入一个加载器是正确的方法我不知道为什么它会是Func类型
我希望界面符合
的界限public interface IXmlDocumentLoader
{
XDocument LoadDocument(string url);
}
然后你的代码看起来像
private readonly IXmlDocumentLoader _xmlUrlLoader;
public MyConstructor(IXmlDocumentLoader xmlUrlLoader)
{
_xmlUrlLoader = xmlUrlLoader;
}
private void ProcessData(string url)
{
var xDocument = this._xmlUrlLoader(url);
// the rest of the code
}
但我认为,出于分离关注的原因,文档加载器肯定应该属于自己的类。
答案 1 :(得分:3)
我更喜欢将逻辑与访问资源分开。在您的情况下,我将文档传递给处理函数:
void ProcessData(XDocument xDocument);
您可以在不嘲笑任何内容的情况下测试该功能。然后,如果您愿意,可以在顶部添加一个薄的包装来进行加载。
void ProcessUrl(string url);
{
var xDocument = XDocument.Load(url);
ProcessData(xDocument);
}
你可以使用模拟来对包装器进行单元测试,但我个人并没有从中看到很多好处。我更喜欢仅在集成测试中使用这些包装器。