我正在使用带有nUnit的C#对我的项目进行单元测试,并且我试图编写一些单元测试来确保调用某个Exception但我的测试仍然失败。在经过大量测试以解决问题之后,我设法确定了它的原因,并创建了一个小代码示例,显示了我的问题。
我的单元测试代码:
[Test]
public void TestExceptionIsRaised()
{
var ex = Assert.Throws<UnauthorizedAccessException>(() => TestExceptionMethod());
StringAssert.Contains("Attempted to perform an unauthorized operation", ex.Message);
}
我的方法没有错误检查:
public void TestExceptionMethod()
{
throw new UnauthorizedAccessException();
}
现在,如果我使用上述方法运行该单元测试...它会抛出异常,nUnit会检测到它并且测试通过。但是,这段代码是一个问题,因为它没有错误处理,如果我这样发布它会崩溃。
所以为了解决这个问题,我在我的方法中添加了一些错误处理,如下所示:
public void TestExceptionMethod()
{
try
{
throw new UnauthorizedAccessException();
}
catch (UnauthorizedAccessException ex)
{
// Do something about the error
}
}
但是现在当我运行单元测试时,它会因此错误而失败:
预期:System.UnauthorizedAccessException 但是:null
因此,我不必在单元测试或正确的错误处理之间进行选择,而是试图像这样重新抛出错误:
public void TestExceptionMethod()
{
try
{
throw new UnauthorizedAccessException();
}
catch (UnauthorizedAccessException ex)
{
// Do something about the error
throw;
}
}
最后,现在一切正常。单位测试每次都通过。我的方法仍然可以捕获错误并对其做些什么。
但是从我所听到的情况来看,重新抛出这样的错误并不是一种好的做法。所以我只是想知道我的解决方案&#34;正确&#34;?或者是否有更好的单元测试方法,而不必从原始方法中删除try / catch块?
答案 0 :(得分:2)
然而,从我所听到的情况来看,保持这种做法并不是一件好事 重新抛出这样的错误???
重新抛出异常没有错。在应用程序运行一些日志代码而不恢复应用程序状态之后,重新抛出异常实际上是最佳做法。
或者没有更好的单元测试方法 必须从原始方法中删除try / catch块?
我不确定我明白你的意思。但是如果你期望从你的方法中抛出异常,那么无论是直接抛出还是重新抛出你的测试都必须有一个例外。如果您try/catch
喜欢这样:
public void TestExceptionMethod()
{
try
{
throw new UnauthorizedAccessException();
}
catch (UnauthorizedAccessException ex)
{
// Do something about the error
}
}
测试将无法确定,因为吞下例外。测试无法检测到方法内部存在异常。
答案 1 :(得分:1)
将您的考试翻译成英语:
“我希望方法TestExceptionMethod抛出一个 UnauthorizedAccessException。其中的消息将包含一个 带有更多细节的字符串。“
如果没有抛出异常,这个测试永远不会通过。如果您不想抛出异常,则需要更改测试。如果您确实希望抛出异常,那么您所做的就是正确的。
这是正确的吗?
这取决于。如果您正在做的是一个特殊问题,那么抛出异常。让程序崩溃。修复错误。
另一方面,如果这是预期的事情,例如糟糕的用户输入,边界条件,请尽可能处理。如果您无法从问题中恢复,则抛出异常。
答案 2 :(得分:0)
异常处理效果不佳会使调试变得更加困难,尤其是在吞下异常时,或者创建新的异常实例并抛出丢失原始异常的堆栈跟踪时。当你需要在调用堆栈的更高处需要更抽象的异常时,有时后者是可取的,在这种情况下,你可以将原始异常添加为内部异常以保持对堆栈跟踪的访问。