JUnit – 我应该在tearUown中为在setUp中实例化的资源分配null吗?
我正在阅读一本关于JUnit的书,作者建议在tearDown方法中使资源归零。 为什么? 这不是GC的工作吗? 它会严重伤害吗?
让我们想到这样的例子:
public class SomeTest extends TestCase { Vector vector; List list; protected void setUp() { vector = new Vector(); list = new ArrayList(); } // messing with resources // adding, deleting, testing whatever protected void tearDown() { vector = null; list = null; } }
你怎么看? tearDown中的代码是否必要?
是的,这确实是必要的。
你看,JUnit实际上会为每个测试方法创建一个单独的Test
类实例,而Junit3测试运行器(JUnit4不是这样)会保留这些实例,直到整个测试套件完成。
因此,如果您的(JUnit3)测试类具有占用大量内存的字段,则在拥有大量测试方法时,您可以轻松地耗尽堆空间。 当然,如果示例代码中的那些集合只包含少量短字符串,那么无关紧要。
这取决于您认为的资源。 虽然堆空间是一种资源,但是你可以在你(YMMV)之后清除GC。
可能导致问题的事情是Closable
如数据库连接/打开文件和流等,应该在使用后始终关闭,以防止长时间运行的代码中的恶意。
我曾经遇到过一种情况,即对某些hibernate代码的集成测试没有正确清理并导致一些非常奇怪的错误。 花了很多时间才发现并激怒了我,以至于我再也不会犯同样的错误了。
JUnit 4.x样式测试和测试套件的处理方式与JUnit 3.x测试套件不同。
TL; DR:你应该在JUnit3风格的测试中将字段设置为null,但是你不需要在JUnit4风格的测试中 。
使用JUnit 3.x样式测试, TestSuite
包含对其他Test
对象(可能是TestCase
对象或其他TestSuite
对象)的引用。 如果您创建一个包含许多测试的套件,那么对于最外层套件的整个运行,将会有对所有叶子TestCase
对象的硬引用。 如果某些TestCase对象在setUp()
中分配占用大量内存的对象,并且对这些对象的引用存储在tearDown()
中未设置为null
字段中,则可能存在内存问题。
换句话说,对于JUnit 3.x样式测试,要运行的测试的规范引用实际的TestCase
对象。 在测试运行期间,从TestCase
对象可到达的任何对象都将保留在内存中。
对于JUnit 4.x样式测试,要运行的测试的规范使用Description对象。 Description
对象是一个值对象,它指定要运行的内容,但不指定如何运行它。 测试由Runner
对象运行,该对象获取测试或套件的Description
并确定如何执行测试。 甚至向测试侦听器通知测试状态也会使用Description
对象。
JUnit4测试用例的默认运行程序JUnit4仅在测试运行期间保持对测试对象的引用。 如果您使用自定义运行器(通过@RunWith
注释),该运行器可能会或可能不会长时间保持对测试的引用。
也许您想知道如果在JUnit4风格的套件中包含JUnit3风格的测试类会发生什么? JUnit4将调用new TestSuite(Class)
,它将为每个测试方法创建一个单独的TestCase
实例。 跑步者将在测试运行的整个生命周期内保留对TestSuite
的引用。
简而言之,如果您正在编写JUnit4样式的测试,请不要担心在拆除时将测试用例的字段设置为null
(当然,还有免费资源)。 如果您正在编写在setUp()
中分配大对象的JUnit3样式的测试并将这些对象存储在TestCase
字段中,请考虑将字段设置为null
。
- Websocket在playframework 2中发送所有客户端的数据
- 尝试运行jar文件时,Manifest主要属性exception的签名文件摘要无效
- HTTPClient“main”java.lang.NoSuchFieldError:INSTANCE at org.apache.http.conn.ssl.SSLConnectionSocketFactory。
- 在批处理中使用JDBC preparedStatement
- 一个很好的网络数学Java库
- superClass的私有成员是否由子类inheritance… Java?
- Java中的字符串替换
- Java堆中的空格/代数之间的比率是否恒定?
- 创建JSON对象并将其转换为Java中的String