3

我有一个方法,它调用 .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 注入到下面的类中:

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
}

有没有更好的办法?

4

2 回答 2

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
}

但我认为出于关注点分离的原因,文档加载器绝对应该在它自己的类中。

于 2013-03-28T16:55:41.987 回答
3

我更喜欢将逻辑与访问资源分开。在您的情况下,我会将文档传递给处理功能:

void ProcessData(XDocument xDocument);

您可以在不模拟任何内容的情况下测试该功能。然后,如果您愿意,可以在顶部添加一个薄包装器来进行加载。

void ProcessUrl(string url);
{
    var xDocument = XDocument.Load(url);
    ProcessData(xDocument);
}

您可以使用模拟对包装器进行单元测试,但就我个人而言,我并没有看到太多收获。我更喜欢仅在集成测试中使用这些包装器。

于 2013-03-28T17:02:23.473 回答