java – 重置JUnit测试的静态字段

我有一组JUnit测试,它们在 Java程序上调用main方法,传入args并检查输出.没关系.

但是,如果我测试的程序具有被更改的静态值,则它们在测试之间将保持不变.这会导致问题.我无法控制正在测试的程序是什么,或者用于静态字段的名称.

我如何确保我的单元测试运行干净,就好像它是从头开始程序,而不保留那些静态字段.有没有办法以某种方式重置它们?

如果没有,我将不得不启动一个运行该程序的新进程,然后检查输出等,但这似乎有点矫枉过正.

编辑 – 请注意我无法控制单元测试正在测试的代码 – 我无法更改其字段名称,不幸的是,我也不会知道他们的字段名称.我想,如果没有开始新的流程,这是不可能的?

解决方法

一般来说,如果你发现你的代码是不可测试的,就像这里的问题一样,它是代码味道的标志,你应该认真考虑重构你的代码,不要使用那些静态字段.

话虽如此,你可能会发现BeanInject library很有帮助.您可以将@After带注释的方法放入测试类中,并使用注入重置静态字段:

Inject.field("thatStaticField").of(thatObjectWithStaticFields).with("default value");

这样,您只需要知道字段名称,但您不必使用字段实际修改类.该库使用反射来做到这一点.

另外,我想到,如果你正在测试包含你无法控制的部件的东西,你为什么不尝试用Mockito来模仿这些部分呢?

编辑/添加:好的,所以你的问题是你甚至不知道类可能有也可能没有的可能静态变量的初始值.我看到了两种可能的方法:1)你必须在第一次加载类时保存它们的值并在每次测试之间重置值,或者2)你必须得到一个全新的类实例.类加载器.

在第1点),你需要使用反射来遍历@BeforeClass方法中的所有字段,将它们的初始值保存到一些Map< String,Object>中.结构,然后重置@Before或@After方法中的值.以下是使用反射循环遍历类的字段的一些主题Loop over all fields in a Java class

关于第2点),你有这方面的指示(涉及类加载器):Java: how to “restart” a static class?

你可以用反射和那些东西做很酷的事情.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...