我正在尝试编写一个 junit 测试来防止一段代码陷入无休止的迭代中,这最终会导致 StackOverflow。
所以我正在寻找一种在运行时减少堆栈大小的方法,这样 Junittest 会更快地失败。
无法将最大堆栈设置为 jvm 参数,因为测试是更大的测试套件的一部分。
我正在尝试编写一个 junit 测试来防止一段代码陷入无休止的迭代中,这最终会导致 StackOverflow。
所以我正在寻找一种在运行时减少堆栈大小的方法,这样 Junittest 会更快地失败。
无法将最大堆栈设置为 jvm 参数,因为测试是更大的测试套件的一部分。
您可以运行一个递归方法,该方法将自行运行给定次数,然后执行给定操作。不过听起来很不稳定:(
就像是:
public void eatStackThenExecute(int depth, Runnable action)
{
// Maybe put some locals here (and use them) to eat more stack per iteration?
if (depth == 0)
{
action();
}
else
{
eatStackThenExecute(depth - 1, action);
}
}
编辑:智能 JVM 可能会在这里优化尾调用,所以我们可能需要在递归调用之后做一些“事情”来阻止这种情况的发生......
Ick'n东西:(
无法在运行时设置堆栈大小,但也许您可以:
thread.getStackTrace()
如果其大小大于 x,则定期轮询并失败;未编译的概念证明代码(未正确检查所有边缘条件):
AtomicBoolean success = new AtomicBoolean(false);
Thread t= new Thread(new Runnable() {
public void run() {
codeToTest();
success.set(true);
}
});
t.start();
while ( t.isAlive() ) {
if ( t.getStackTrace().length > 50 )
fail("Stack trace too large");
Thread.sleep(50);
}
assertTrue(sucess.get());
您只能在启动时设置这样的参数,但是您可以从 Java 启动另一个进程。因此,您可以让您的单元测试以较小的堆栈大小启动第二个进程来执行您的测试。
这有点……嗯,很有趣……但这可能是值得的。