无法获得NUnit的Assert.Throws正常工作

时间:2010-03-05 22:15:14

标签: unit-testing exception dictionary nunit keynotfoundexception

我本可以发誓我已经使用了NUnit的Assert.Throws来确定是否从某个方法抛出了一个特定的异常,但my memory has failed me before。我读了this post here on SO,但它没有回答我的问题,因为我知道正确的语法,而且我不想对返回的异常做任何事情(我不想看看Exception的成员,虽然这可能在路上很有用。)

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

我尝试过这两种方式:

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

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

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

UPDATE 似乎有些人无法重现这一点。这是一个截图:

alt text http://i47.tinypic.com/2qs2hhz.jpg

4 个答案:

答案 0 :(得分:3)

这是一个旧线程,但尝试在Tools-&gt; Options下关闭Visual Studio中的Enable Just My Code。启用此选项后,调试器将尝试提供帮助,并在吞下异常之前停止在代码中的最后一个可能位置。

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

如果关闭“启用我的代码”,Assert.Throws应该可以正常工作。

答案 1 :(得分:2)

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

标记我的测试
[ExpectedException(typeof(KeyNotFoundException))]
public Test ShouldDoTheStuff() {

  ...

}

这对你有用吗?我实际上并没有发现你的代码有任何问题。

答案 2 :(得分:2)

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

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

执行它时,您将在VisualStudio中收到一条警告,指出在用户代码中未处理该异常。如果你看一下callstack,你会看到像

这样的东西
[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"];
}

答案 3 :(得分: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"]);
        }
    }
}