2013-03-28 28 views
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到像下面的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 
} 

有没有什么更好的办法?

+1

我想把URL的责任推到一个层面。所以有一个函数将数据作为字符串或'XDocument'处理,然后对其进行处理,然后在它上面打包下载数据并将其传递给处理函数。没有嘲笑需要。 – CodesInChaos

+0

如果我在哪里,我只是通过xDocument这个方法。 –

+0

@KirillBestemyanov我无法将xDocument传递给它;我不想调用xDocument.Load,这应该被嘲笑/孤立。 –

回答

3

我同意注入装载机是正确的做法我不知道为什么它会是类型的函数功能

我希望沿着

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 
} 

但我认为,由于担心分离的原因文件加载器应该肯定是在它自己的类。

+0

这看起来是注入依赖关系的有效简单方法。缺点是我不得不创建一个包装,它将成为生产代码的一部分,但不会是单元可测试的。 –

3

我更喜欢分离逻辑访问资源。在你的情况我会在文档传递给处理功能:

void ProcessData(XDocument xDocument); 

您可以测试功能,无需任何嘲讽。然后,如果你想要,你可以在加载的顶部添加一个薄包装。

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

你可以使用模拟来单元测试包装,但我个人并没有看到太多的收获。我更愿意仅将这些包装作为集成测试的一部分来使用。

+0

我理解你关于分离访问资源的逻辑,这是可读性提高的一个有效点(可以说),但上述内容不能解决我提出的问题,你会如何嘲笑它?创建一个接口和一个包装? –

+1

@TheLight我主要是在不嘲笑任何东西的情况下测试版本的'XDocument'。我不能说如何或如果我没有上下文测试包装。可能带有“IFileSystem”接口,可能只有集成测试。 |你嘲笑你如何测试是一个风格问题,我更喜欢嘲笑尽可能少。其他人有不同的喜好。 – CodesInChaos

+0

我的意思是运行XDocument.Load()的包装器。我认为ProcessUrl()方法是一个测试单元,尽管它调用了另一种方法,所以我需要模拟它。测试单位并不总是必须是一个属性或一个单一的方法。一组方法甚至类可以被测试,它们仍然是单元测试。如果我将测试我的codse与其他外部资源/系统(文件,数据库,其他Web服务)的集成,那么我会将它们称为集成测试。否则,它都是单元测试。 –

相关问题