8

一段时间以来,我们一直在使用 NUnit 和 VisualStudio 编写 C# .NET 代码。测试异常的风格是

旧语法:

[Test]
[ExpectException(typeof(ExceptionType))] 
public void TestExceptionType()
{

}

现在 NUnit 已经发布了 2.5.2 版本,它引入了Assert.Throws( Type expectedExceptionType, TestDelegate code );这使得异常测试更加灵活。我们的异常测试现在看起来像这样:

新语法:

[Test]
public void TestWithNullBufferArgument()
{
   ArgumentNullException ex = Assert.Throws<ArgumentNullException>(() => _testInstance.TestFunction(null));

   // now you can examine the exception and it's properties
   Assert.AreEqual(ex.Message, "Argument was null");
}

我们的问题是,如果使用 Assert.Throws,当使用 NUnit(控制台或 GUI 运行程序)调试程序时,Visual Studio 会弹出一个窗口,显示未处理的异常。

为了澄清这一点:我们已将包含单元测试的 VS 项目设置为在调试时运行 nunit-x86.exe。(查看项目属性,调试选项卡,启动动作设置为运行nunit-x86.exe)

这会阻止 NUnit 继续测试。可以通过按 F5 继续调试/单元测试,但这不是一个可行的解决方案。

有没有办法避免这种情况?在 Assert.Throws 周围放置一个 try...catch 块没有任何作用,因为异常发生在委托代码中。

我希望有人可以对此有所了解。

4

4 回答 4

7

问题本身出现是因为您很可能启用了仅启用我的代码选项(工具->选项->调试->常规->启用仅我的代码)。

“启用此功能后,调试器仅显示并进入用户代码(“我的代码”),忽略系统代码和其他经过优化或没有调试符号的代码”(请参阅​​“常规、调试、选项对话框” )

通常你有一个 nunit.framework.dll 的发布版本,它没有对应的 nunit.framework.pdb 文件。

所以有2个选项:

  1. 禁用“只是我的代码”功能

  2. 下载 nunit 的源代码(从http://www.nunit.org/index.php?p=download),以调试模式构建它们,将所有 nunit.framework.* (dll, pdb, xml) 放入 lib 或其他目录在您的解决方案中并在您的测试项目中引用该 nunit.framework.dll 。

希望这可以帮助。

于 2010-02-08T19:35:40.720 回答
2

同样的问题也困扰了我很长一段时间,我做了一些测试,发现如下:

如果一个库(在这种情况下为 nunit)是在调试信息设置为“无”的情况下编译的,那么如果使用该库执行类似于下面的构造并且委托的代码抛出异常,则 VS 停止抱怨用户未处理的异常代码。

库代码:

public static Exception Throws(TestDelegate code, string message)
{
    Exception caughtException = null;

    try
    {
        code();
    }
    catch (Exception ex)
    {
        caughtException = ex;
    }        

    return caughtException;
}

客户端代码:

private void btnTest_Click(object sender, EventArgs e)
{
  var ex = MyAssert.Throws(() => { throw new Exception(); }, "");    
}

将库项目的调试信息设置为“none”以外的任何其他选项都可以解决问题,即调试器不再停止那些有点“未处理”的异常。我用上面的代码用 nunit 和我自己的手动库测试了它(从 nunit 的 Throws 方法中获取了一个片段)。我想这是VS的一个特性或“特性”。

它给我们留下的选择不多:

  1. 如前所述过滤异常

  2. 重新编译 nunit.framework.dll 以供本地使用,以避免那些烦人的停止

其他选项可能是联系 MS 或 NUnit 团队或两者联系,并要求他们调查/澄清问题并以最低级别的调试信息恭敬地编译 NUnit。

编辑:

又找到了一种选择。

  1. 在我的情况下,取消选中“在模块加载时抑制 JIT 优化”也可以解决问题,即使在没有调试信息的情况下编译库也是如此。但是,它仅在项目在发布配置中运行时才有效。
于 2010-02-09T13:25:47.510 回答
1

我认为你被 NUnit 断言蒙蔽了。您可以通过简单的 try/catch 来实现相同的目标。

try
{
  _testInstance.TestFunction(null);
  Assert.Fail("The method should have thrown...");
}catch{}

现在,您拥有所需的一切。如果没有抛出异常并且您的常规代码可以按预期处理异常,您将失败。

于 2010-02-05T14:55:03.600 回答
-1

是否可以通过禁用异常来实现。打开 Debug/Exceptions 菜单,然后搜索您的 Exception。

于 2010-01-18T15:36:02.357 回答