重置JUnit测试的静态字段 [英] Resetting static fields for JUnit tests

查看:118
本文介绍了重置JUnit测试的静态字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a set of JUnit tests which call the main method on a Java program, passes in args and checks the output. That's fine.

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

However, if the program I am testing has static values which are altered, they will remain the same between tests. This causes a problem. I have no control over exactly what the program is that is being tested, or the names used for static fields.

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

How can I ensure that my Unit tests run cleanly, as if it is starting the program from scratch, without keeping those static fields. Is there a way to reset them in some way?

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

If not, I will have to fire up a new process which runs the program, then check the output etc, but this seems a little overkill.

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

Edit - Please note I have no control over the code which the unit tests are testing - I can't change their field names, and unfortunately, I also won't know their field names. I am thinking that makes this not possible, without starting a new process?

推荐答案

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

In general if you find your code to be untestable, like is the question here, it's a sign of a code smell, and you should seriously consider refactoring your code to not to use those static fields.

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

Having said that, you might find the BeanInject library helpful. You could put an @After annotated method into your test class and have it reset the static fields using the injection:

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

这样你只需知道字段名称,但你不必真正知道用字段修改类。该库使用反射来做到这一点。

That way you only need to know the field names but you don't have to be able to actually modify the class with the fields. The library does that using reflection.

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

Additionally, it came to my mind that if you are testing something that contains parts that you cannot control, why don't you try to mock those parts with, say, Mockito?

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

EDIT/ADD: OK, so your issue is that you don't even know the initial values of the possible static variables the classes may or may not have. I see two possible approaches: 1) You'd have to either save their values when the class is loaded for the first time and reset the values between each test, or 2) you have to get an entirely new instance of the class from the class loader.

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

On point 1), you'd need to use reflection to loop through all the fields in your @BeforeClass method, save their initial values into some Map<String,Object> structure, and then reset the values in your @Before or @After method. Here's some topic on looping through the fields of a class using reflection: Loop over all fields in a Java class

关于第2点),您可以在此处获得相关说明(涉及类加载器):Java:如何重启一个静态类?

Regarding point 2), you have the instructions for that (involving class loaders) here: Java: how to "restart" a static class?

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

It's pretty cool what you can do with reflection and that stuff. :)

这篇关于重置JUnit测试的静态字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆