nunit,既不断言也不是[预期的]陷入异常
题
在开始之前,我想清楚地表明,我已经在这两个方面都检查过解决方案 这个问题 和 这个问题.
测试方法
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
相反是发生(当然,我的任何一个测试用例都没有处理,因为 永远不要扔).
最初,第一种测试方法(ExecuteDataSetThrowsForNullConnection
)看起来就像第二个(ExecuteDataSetThrowsForNullSql
)。什么时候 Assert.Throws
我没有发现例外,我做了一些研究,并指出有些人建议使用 ExpectedException
反而。我相应地修改了测试代码,但无济于事。
对于记录,这是32位.NET 3.5代码,根据Nunit 2.5.9进行了测试。我正在使用testdriven.net进行Visual Studio集成,并且已安装了最新版本的NCOVE和NDEPENT。
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);
}
}
解决方案
我的猜测是,您并没有真正测试自己认为的代码。尝试放一些 Console.WriteLine
陈述中,看看它们是否打印。如果您在 throw
声明并在调试器中运行测试,断点会受到打击吗?如果控制权传递给下一个陈述,则意味着从来没有抛出过例外 - 不可能以使执行方式继续以抛出方式继续执行的方式,除非您找到了一个 真的 怪异的CLR错误。
我写了 很多 像这样的代码,在Nunit中从未失败。
顺便说一句,我认为这是一个很好的做法,将参数名称包含在参数exceptions中,所以我已经写了:
if (connection == null)
{
throw new ArgumentNullException("connection");
}
if (sql == null)
{
throw new ArgumentNullException("sql");
}
这是一个不幸的问题,即渴望并重复代码中的参数名称作为字符串...但是,正确正确(尤其是使用Resmanter帮助验证名称)相当容易的问题,如果这种触发在生产中,这可能真的很有用。 (有一些粗略的黑客以其他方式验证论点,但我怀疑您不想看到这些论点...)