在开始之前,我想明确一点,我已经检查过这个问题和这个问题的解决方案。
测试方法
public static DataSet ExecuteDataSet(this SqlConnection connection, string sql)
{
if (null == connection || null == sql)
{
throw new ArgumentNullException();
}
using (var command = connection.CreateCommand())
{
// Code elided for brevity
}
}
测试方法
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ExecuteDataSetThrowsForNullConnection()
{
((SqlConnection)null).ExecuteDataSet("SELECT TOP 1 * FROM prep");
}
[Test]
public void ExecuteDataSetThrowsForNullSql()
{
Assert.Throws<ArgumentNullException>(
() => Resource.Connection.ExecuteDataSet(null)
);
}
奇怪的行为
这两个版本的测试方法都没有捕捉到ArgumentNullException
在进入方法时立即抛出的那个ExecuteDataSet
。控制流进行到下一行 ( using (var command = connection.CreateCommand())
) 并且NullReferenceException
发生了 a (当然,我的任何一个测试用例都没有处理它,因为它永远不应该被抛出)。
最初,第一个测试方法 ( ExecuteDataSetThrowsForNullConnection
) 看起来就像第二个 ( ExecuteDataSetThrowsForNullSql
)。当Assert.Throws
未能捕捉到异常时,我做了一些研究并注意到有些人建议使用它ExpectedException
。我相应地修改了测试代码,但无济于事。
作为记录,这是 32 位 .NET 3.5 代码,在 NUnit 2.5.9 下测试。我正在使用 TestDriven.NET 进行 Visual Studio 集成,并安装了最新版本的 NCover 和 NDepend。
TL;DR 问题
为什么测试方法没有捕捉到抛出的异常,我该如何解决?
编辑
此版本的测试方法有效。
[Test]
public void ExecuteDataSetThrowsForNullConnection()
{
try
{
((SqlConnection)null).ExecuteDataSet("SELECT TOP 1 * FROM prep");
}
catch(ArgumentNullException e)
{
Assert.AreEqual(true, true);
}
catch (Exception e)
{
Assert.Fail("Expected ArgumentNullException, but {1} was thrown instead.", e.GetType().Name);
}
}