Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果我使用try/catch,为什么我的异常C#单元测试会失败?_C#_Unit Testing_Nunit - Fatal编程技术网

如果我使用try/catch,为什么我的异常C#单元测试会失败?

如果我使用try/catch,为什么我的异常C#单元测试会失败?,c#,unit-testing,nunit,C#,Unit Testing,Nunit,我正在使用C#with nUnit对我的项目进行单元测试,我正在尝试编写一些单元测试,以确保调用某个异常,但我的测试一直失败。在进行了大量测试以解决问题之后,我设法找出了问题的原因,并创建了一个小代码示例,该示例显示了我的问题视图 我的单元测试代码: [Test] public void TestExceptionIsRaised() { var ex = Assert.Throws<UnauthorizedAccessException>((

我正在使用C#with nUnit对我的项目进行单元测试,我正在尝试编写一些单元测试,以确保调用某个异常,但我的测试一直失败。在进行了大量测试以解决问题之后,我设法找出了问题的原因,并创建了一个小代码示例,该示例显示了我的问题视图

我的单元测试代码:

    [Test]
    public void TestExceptionIsRaised()
    {
        var ex = Assert.Throws<UnauthorizedAccessException>(() => TestExceptionMethod());
        StringAssert.Contains("Attempted to perform an unauthorized operation", ex.Message);
    }
现在如果我用上面的方法运行单元测试。。。它抛出异常,nUnit检测到异常,测试通过。然而,这段代码是一个问题,因为它没有错误处理,如果我像这样发布它,它将崩溃

为了解决这个问题,我在方法中添加了一些错误处理,如下所示:

   public void TestExceptionMethod()
    {
        try
        {
            throw new UnauthorizedAccessException();
        }
        catch (UnauthorizedAccessException ex)
        {
            // Do something about the error
        }
    }
public void TestExceptionMethod()
        {
            try
            {
                throw new UnauthorizedAccessException();
            }
            catch (UnauthorizedAccessException ex)
            {
                // Do something about the error
                throw;
            }
        }
public void TestExceptionMethod()
    {
        try
        {
            throw new UnauthorizedAccessException();
        }
        catch (UnauthorizedAccessException ex)
        {
            // Do something about the error
        }
    }
但现在,当我运行单元测试时,它失败了,出现以下错误:

应为:System.UnauthorizedAccessException 但是是:空

因此,我不必在单元测试或正确的错误处理之间进行选择,而是尝试像这样重新抛出错误:

   public void TestExceptionMethod()
    {
        try
        {
            throw new UnauthorizedAccessException();
        }
        catch (UnauthorizedAccessException ex)
        {
            // Do something about the error
        }
    }
public void TestExceptionMethod()
        {
            try
            {
                throw new UnauthorizedAccessException();
            }
            catch (UnauthorizedAccessException ex)
            {
                // Do something about the error
                throw;
            }
        }
public void TestExceptionMethod()
    {
        try
        {
            throw new UnauthorizedAccessException();
        }
        catch (UnauthorizedAccessException ex)
        {
            // Do something about the error
        }
    }
最后,一切都正常了。每次单元测试都通过。我的方法仍然可以捕捉错误,并对其采取措施

然而,据我所知,像这样不断地重复抛出错误是不好的做法???所以我只是想知道我的解决方案是否“正确”?或者,有没有更好的方法来对异常进行单元测试,而不必从原始方法中删除try/catch块

然而,据我所知,保持沉默并不是一个好的习惯 你会犯这样的错误吗

重新抛出异常没有什么错。实际上,在应用程序运行一些日志代码后重新抛出异常是一种最佳做法,而不恢复应用程序状态

或者,有没有更好的方法来对异常进行单元测试,而无需测试 必须从原始方法中删除try/catch块吗

我不太明白你的意思。但是,如果您希望从方法中抛出异常,那么无论是直接抛出还是重新抛出,您的测试都必须通过一个异常。如果您
像这样尝试/catch

   public void TestExceptionMethod()
    {
        try
        {
            throw new UnauthorizedAccessException();
        }
        catch (UnauthorizedAccessException ex)
        {
            // Do something about the error
        }
    }
public void TestExceptionMethod()
        {
            try
            {
                throw new UnauthorizedAccessException();
            }
            catch (UnauthorizedAccessException ex)
            {
                // Do something about the error
                throw;
            }
        }
public void TestExceptionMethod()
    {
        try
        {
            throw new UnauthorizedAccessException();
        }
        catch (UnauthorizedAccessException ex)
        {
            // Do something about the error
        }
    }

测试肯定会失败,因为异常被吞没。测试无法检测到方法内部存在异常。

将测试翻译成英语您说:

“我希望TestExceptionMethod方法抛出一个 UnauthorizedAccessException。其消息将包含 请输入更多详细信息。”

如果不抛出异常,此测试将永远不会通过。如果不希望抛出异常,则需要更改测试。如果您确实希望抛出异常,那么您所做的是正确的

这是正确的吗?

视情况而定。如果你正在做的是一个异常问题,那么抛出一个异常。让程序崩溃。修复错误


另一方面,如果这是预期的情况,例如糟糕的用户输入、边界条件,请尽可能处理它。如果无法从问题中恢复,则抛出异常。

异常处理不当会使调试更加困难,特别是当异常被吞没时,或者当创建新异常实例并抛出时,会丢失原始异常的堆栈跟踪。有时,当您需要调用堆栈更高层的更抽象的异常时,后者是可取的,在这种情况下,您可以将原始异常添加为内部异常,以保持对堆栈跟踪的访问。

哦,我想我开始明白您的意思了。我唯一不明白的是,在我开始为异常编写单元测试之前,我从未使用过Throw关键字。我只是使用Try{something}Catch(SomeException ex){MessageBox.Show(ex.Message)};即使我没有将异常抛出catch块,它也能很好地捕获异常。因此,我不能100%确定为什么这样做有效,但现在我必须在catch块中重新抛出它们,以使单元测试有效?@Calcolat:当您使用
Assert.Throws
时,必须抛出异常
。你在之前的单元测试中是否使用了
Assert.Throws
?啊,我现在明白了。不,我以前没用过Assert.Throws。我只做了正常的单元测试,不测试任何异常。我现在明白你的意思了。如果我没有对异常进行单元测试,我就不必重新抛出异常。但是如果我使用的是Assert.Throws,那么必须抛出异常,因此我必须重新抛出它。对的