我正在尝试编写一个单元测试来覆盖我们的“最后机会异常处理程序”中的代码。
当提到最后机会异常处理时,我正在谈论事件的事件处理程序:
Application.ThreadException AppDomain.CurrentDomain.UnhandledException
或多或少我正在验证正在生成日志,详细说明异常产生的信息。我的测试类似于:
[Test]
public void TestMethod()
{
//Setup log4net ConsoleAppender here
//hooking a MemoryStream to the Console.SetOut done here
ExceptionHandler.InstallExceptionHandler();
Thread exceptionThread = new Thread(ThrowException);
Thread.Start();
//read stream here
Assert.That(streamContainsExceptionText);
}
private void ThrowException() {
throw new Exception("Unhandled Exception");
}
异常处理程序是一个单例,当“已安装”时,只会将处理程序添加到先前给定的事件中。奇怪的是,我没有一致的结果。断开和调试似乎不是一个选项,因为它似乎介于异常和ExceptionHandler之间。
我在整个代码中放置了几个“Console.WriteLine()”语句来验证代码失败的位置,但这不一致。我认为它与测试框架杀死线程或可能某种垃圾收集有关。
有没有人有测试这样一段代码的经验?或者您是否了解我为何会看到这种行为?
我正在使用NUnit 2.4并使用ReSharper在IDE中运行它。
答案 0 :(得分:2)
这是竞争条件,您的线程可能并不总是有时间进行异常+记录它。
加入线程,所以在线程完成后继续。
Thread exceptionThread = new Thread(ThrowException);
exceptionThread.Start();
exceptionThread.Join();
//read stream, and rest of the test
此外,您可能希望在加入呼叫上设置超时。
答案 1 :(得分:1)
您是否有可能在线程启动之前尝试从流中读取值,然后结束?
对于这种事情,我们将把流读入循环(伪代码):
while (!timed out) {
read from stream;
if (message is in stream) {
set success flag;
break;
}
sleep;
}
if (!success flag) {
throw test failure;
}