5

我可以发誓我已经使用 NUnit 的 Assert.Throws 来确定某个方法是否抛出了特定的异常,但是我之前的记忆让我失望了。我在 SO 上阅读了这篇文章,但它没有回答我的问题,因为我知道正确的语法,并且我不想对返回的异常做任何事情(我不想查看异常成员,尽管这在以后可能会有用)。

我编写了单元测试来证明我对 Dictionary 的使用缺乏了解,并且无法让它处理抛出的 KeyNotFoundException。当我运行时,我得到一个未处理的 KeyNotFoundException 错误,而不是 NUnit 捕获它并通过测试。我确认我没有设置 VS IDE 来中断抛出的 .NET 异常。

我试过这两种方法:

Assert.Throws( typeof(KeyNotFoundException), () => value = prefs["doesn't exist"]);

Assert.Throws<KeyNotFoundException>( () => value = prefs["doesn't exist"]);

但两者都会导致未处理的异常。我在这里想念什么?

UPDATE似乎其他人无法重现这一点。这是一个屏幕截图:

替代文字

4

4 回答 4

4

这是一个旧线程,但请尝试在 Visual Studio 中的 Tools->Options 下关闭 Enable Just My Code。启用此功能后,调试器会尝试提供帮助,并在异常被吞没之前停止在代码中的最后一个可能点。

或者,至少这是我对它的理解。

如果您关闭 Enable Just My Code,Assert.Throws 应该可以正常工作。

于 2011-04-21T23:39:02.900 回答
2

不是直接的答案,但我个人更喜欢用

[ExpectedException(typeof(KeyNotFoundException))]
public Test ShouldDoTheStuff() {

  ...

}

这对你有用吗?我实际上并没有看到您的代码本身有任何问题。

于 2010-03-05T22:47:16.660 回答
2

调试器说明您的异常没有由用户代码处理,这在技术上是正确的。为了演示,我将使用提供的示例测试 sgreeve

[Test]
public void demonstrateThatExceptionThrown()
{
    string value;
    Dictionary<string, string> test = new Dictionary<string, string>();
    Assert.Throws(typeof(KeyNotFoundException), () => value = test["h"]);
}

当您执行它时,您将在 VisualStudio 中收到一条警告,指出该异常未在用户代码中处理。如果您查看调用堆栈,您会看到类似

[External Code]
CodeTests.DLL!CodeTests.MiscTests.demonstrateThatExceptionThrown.AnonymousMethod()
[External Code]
CodeTests.DLL!CodeTests.MiscTests.demonstrateThatExceptionThrown()
[External Code]

因为您已经指定了一个委托,所以在创建的“AnonymousMethod”中发生了异常。这是由 .Net 框架调用的。调试器正在停止,因为您的委托在将异常传递回框架之前没有处理异常。它并不关心它可能在您的代码中处理的堆栈的更进一步(可能是因为无法保证外部代码将正确处理异常。)

要让 VisualStudio 将此视为已处理的异常,请使用 ExpectedException 属性并删除委托,如下所示:

[Test]
[ExpectedException(typeof(KeyNotFoundException))]
public void demonstrateThatExceptionThrown()
{
    string value;
    Dictionary<string, string> test = new Dictionary<string, string>();
    value = test["h"];
}
于 2010-04-27T18:57:34.600 回答
0

最近更新的答案!

在我们添加到这个答案的评论中的对话之后,我怀疑 nunitit 测试运行器是这里的问题。我不相信您的测试有任何问题,因为我使用 NUnit GUI 或出色的 Resharper 测试运行程序执行它都没有问题。

更新的答案

在看到您的屏幕截图后,我尝试使用调试器逐步完成我的测试,并看到关于未处理异常的完全相同的提示。如果我继续跳过该错误,则当我到达断言末尾时测试通过。

当我使用 NUnit GUI 或 Resharper 4.5 测试运行器在非调试模式下运行测试时,测试每次都按预期通过。

很抱歉问了一个明显的问题,但是你用什么来执行你的测试?即哪个测试运行器?

我执行的确切代码是:

using System;
using System.Collections.Generic;
using NUnit.Framework;

namespace ClassLibrary1
{
    [TestFixture]
    public class DictionaryTest
    {


        [Test]
        public void demonstrateThatExceptionThrown()
        {
            string value;
            Dictionary<string, string> test = new Dictionary<string, string>();
            Assert.Throws(typeof(KeyNotFoundException), () => value = test["h"]);
        }
    }
}
于 2010-03-05T22:45:41.987 回答