阅读并接受单元测试,试图理解下面的帖子,解释了静态函数调用的艰辛.
我不清楚这个问题.我一直认为静态函数是一种在类中舍入实用函数的好方法.例如,我经常使用静态函数调用来初始化,即:
Init::loadConfig('settings.php');
Init::setErrorHandler(APP_MODE);
Init::loggingMode(APP_MODE);
// start loading app related objects ..
$app = new App();
Run Code Online (Sandbox Code Playgroud)
//阅读帖子后,我现在的目标是......
$init = new Init();
$init->loadConfig('settings.php');
$init->loggingMode(APP_MODE);
// etc ...
Run Code Online (Sandbox Code Playgroud)
但是,我为这堂课写的几十个测试是一样的.我什么都没改变,他们仍然都过去了.难道我做错了什么?
该职位的作者陈述如下:
静态方法的基本问题是它们是过程代码.我不知道如何对程序代码进行单元测试.单元测试假设我可以单独实例化我的应用程序.在实例化期间,我使用mocks/friendlies连接依赖项,这取代了真正的依赖项.使用程序编程没有任何"连线",因为没有对象,代码和数据是分开的.
现在,我从帖子中了解到静态方法创建了依赖关系,但是没有直观地理解为什么人们不能像常规方法那样容易地测试静态方法的返回值?
我将避免使用静态方法,但我想知道WHEN静态方法是否有用,如果有的话.从这篇文章看来,静态方法与全局变量一样邪恶,应尽可能避免.
关于该主题的任何其他信息或链接将不胜感激.
最近,我一直在思考"模拟"从我试图测试的类中调用的静态方法的最佳方法.以下面的代码为例:
using (FileStream fStream = File.Create(@"C:\test.txt"))
{
string text = MyUtilities.GetFormattedText("hello world");
MyUtilities.WriteTextToFile(text, fStream);
}
Run Code Online (Sandbox Code Playgroud)
我知道这是一个相当糟糕的例子,但它有三个静态方法调用,它们略有不同.File.Create函数访问文件系统,我没有该函数.MyUtilities.GetFormattedText是我拥有的一个函数,它纯粹是无状态的.最后,MyUtilities.WriteTextToFile是我拥有的一个函数,它访问文件系统.
我最近一直在思考的是,如果这是遗留代码,我怎么能重构它以使它更可单元测试.我听过几个不应该使用静态函数的论点,因为它们很难测试.我不同意这个想法,因为静态函数是有用的,我不认为应该丢弃一个有用的工具只是因为正在使用的测试框架无法很好地处理它.
经过大量的搜索和审议,我得出的结论是,基本上可以使用4种模式或实践来使函数调用静态函数可单元测试.这些包括以下内容:
我听过很多关于前三种做法的讨论,但是当我在考虑这个问题的解决方案时,我想到了函数依赖注入的第四个想法.这类似于在接口后面隐藏静态函数,但实际上不需要创建接口和包装类.这方面的一个例子如下:
public class MyInstanceClass
{
private Action<string, FileStream> writeFunction = delegate { };
public MyInstanceClass(Action<string, FileStream> functionDependency)
{
writeFunction = functionDependency;
}
public void DoSomething2()
{
using (FileStream fStream = File.Create(@"C:\test.txt"))
{
string text = MyUtilities.GetFormattedText("hello world");
writeFunction(text, fStream);
}
}
}
Run Code Online (Sandbox Code Playgroud)
有时,为静态函数调用创建接口和包装类可能很麻烦,并且它可能会污染您的解决方案,其中许多小类的唯一目的是调用静态函数.我只是编写易于测试的代码,但这种做法似乎是一个糟糕的测试框架的解决方法.
当我考虑这些不同的解决方案时,我开始理解上面提到的所有4种做法都可以应用于不同的情况.以下是我认为应用上述实践的正确条件 …
我一直在读,使用TDD时往往会避免使用静态方法,因为它们往往难以模拟.我发现,单元测试最简单的方法是一个具有简单功能的静态方法.不必实例化任何类,鼓励简单,做一件事,"独立"等方法.
有人可以解释TDD最佳实践和务实轻松之间的差异吗?
谢谢