C#:如何测试StackOverflowException
假设你有一种方法可能会陷入无休止的方法调用循环,并导致StackOverflowException异常。 例如我在这个问题中提到的天真的RecursiveSelect
方法。
从.NET Framework 2.0版开始,StackOverflowException对象不能被try-catch块捕获,并且相应的进程默认终止。 因此,建议用户编写代码来检测和防止堆栈溢出。 例如,如果您的应用程序依赖于递归,请使用计数器或状态条件来终止递归循环。
考虑到这个信息(来自这个答案),因为这个异常不能被捕获,甚至有可能为这样的东西写一个测试吗? 或者如果测试失败了,那么测试是否会实际上破坏整个测试套件?
注意:我知道我可以试试看看会发生什么,但我更关心它的一般信息。 就像,不同的测试框架和测试运行者会以不同的方式处理这个问题吗 即使有可能,我是否应该避免这样的测试?
你需要解决停机问题! 这会让你变得富有和着名:)
如何检查assert语句中栈的帧数?
const int MaxFrameCount = 100000;
Debug.Assert(new StackTrace().FrameCount < MaxFrameCount);
在你的相关问题的例子中,这将是(昂贵的assert语句将在发布版本中被删除):
public static IEnumerable<T> SelectRecursive<T>(this IEnumerable<T> subjects, Func<T, IEnumerable<T>> selector)
{
const int MaxFrameCount = 100000;
Debug.Assert(new StackTrace().FrameCount < MaxFrameCount);
// Stop if subjects are null or empty
if(subjects == null || !subjects.Any())
yield break;
// For each subject
foreach(var subject in subjects)
{
// Yield it
yield return subject;
// Then yield all its decendants
foreach (var decendant in SelectRecursive(selector(subject), selector))
yield return decendant;
}
}
这不是一个普通的测试,因为你需要预期它会发生,而且你只能检查帧数而不是实际的堆栈大小。 也无法检查另一个呼叫是否会超出堆栈空间,您所能做的只是粗略估计总共有多少个呼叫将适合您的堆栈。
这是邪恶的,但你可以在一个新的过程中把它旋转起来。 从单元测试启动进程并等待它完成并检查结果。
链接地址: http://www.djcxy.com/p/80757.html