Mik*_*ike 2 c# tdd dependency-injection
自从关注DI和TDD之后,我对何时应该创建私有方法感到困惑.您能否告诉我在制定方法私有保持可测试性和依赖注入时,应该考虑哪些经验法则?
我相信一个例子可能会有所帮助:
假设我有一个包含3个方法的接口,如下所示:
public interface IWordFrequencyAnalyzer
{
int CalculateHighestFrequency(string forText);
int CalculateFrequencyForWord(string text, string word);
IList<IWordFrequency> CalculateMostFrequentNWords(
string text, int n);
}
Run Code Online (Sandbox Code Playgroud)
现在,我可以编写一个类,它可以实现一个私有方法,它接受一个字符串,并可以计算其中的单词的频率,然后在每个公共方法中,我可以根据它的要求进行操作.在这种情况下,我将是能够测试合同.
要么
我可以将私有方法提取到单独的类中,例如WordProcessor,它实现IWordProcessor,使用单个公共方法将句子拆分为单词并将其作为依赖项传递给IWordFrequencyAnalyzer的实现.这样,分割单词的实现也是可测试的.
你会建议采用哪种方法?
谢谢,-Mike
由于越来越多地使用DI和TDD,我最终越来越少地使用私有方法,但原因并不是因为我需要将它们公开用于测试.更重要的是,作为使用DI的副产品,我正在学习更多关于将SOLID原则应用于我的代码的知识,而这(反过来)正在引导我编写整体方法较少且几乎没有私有的类.
所以,假设您在课程的各种方法中使用了一段代码.你知道DRY,你将它重构为私有方法,一切都很好.除了通常你意识到你可以概括那个私有方法做什么并将该功能作为类的外部依赖注入:这样,你可以测试它并模拟它,当然,但最重要的是你可以重用那个方法甚至在其他课程或其他项目,如果需要.将其移出原始类是单一责任原则的应用.
正如我所说,我对代码的改变并不直接取决于我使用TDD或DI的事实,但它是TDD鼓励我强制执行的原则的副产品以及DI容器在组成许多小的时候提供的便利性这种方法产生的类.
编辑:您添加到您的问题的示例中的第二种方法是我所谈论的一个很好的例子.您的新WordProcessor类现在可测试的事实是一个优点,但它现在可组合和可重用的事实是真正的好处.
您的方法应该是private除非它们需要public用于您的应用程序,而不是您的测试.
一般来说,你不应该public只是为了支持单元测试(internal可能会有帮助).在这种情况下,您通常应该测试public接口,而不是private类的详细信息,这些更有可能改变并破坏您的测试.
如果您可以访问副本,Roy Osherove的" 单元测试艺术 "可以很好地解决这个问题