【问题标题】:Issue with Assert.Throws Exception in NUnit testingNUnit 测试中的 Assert.Throws 异常问题
【发布时间】:2014-01-04 01:26:11
【问题描述】:

我是第一次尝试 NUnit、单元测试和集成测试。我一直在阅读并做很多在线课程。我相信你很清楚,这是了解理论并在实践中进行的事情。

我被困在一个特定的测试中。我拥有的应用程序在 C# .Net 3.5 中。

我试图断言具有特定错误输入的方法将引发特定异常。 当我使用与测试相同的输入运行该方法时,会引发预期的异常。

被测试的方法代码是:

 private static bool FilePathHasInvalidChars(string userInputPath)
{
    try
    {
        Path.GetFullPath(userInputPath);//this is where the warning appears

    }
    catch (Exception e)
    {
        Log.Error(String.Format(
            "The Program failed to run due to invalid characters or empty string value for the Input Directory. Full Path : <{0}>. Error Message : {1}.",
            userInputPath, e.Message), e);
        return true;

    }
    return false;
}

如果提供的输入目录不符合条件,我想检查上面的代码是否可以捕获异常。

我目前的单元测试是:

    [Test]
    public void can_throws_exception_for_empty_string()
    {
        var testDirectory = "";
        var sut = new DirectoryInfoValidator();

        Assert.Throws<ArgumentNullException>(() => sut.FilePathHasInvalidChars(testDirectory));
    }

我遇到的问题是测试总是失败,如果我检查返回它表明它预期 ArgumentNull 异常但为空。我截取了测试输出的屏幕截图:

知道我可能做错了什么吗? 编辑:顺便说一句,我也尝试过使用

[ExpectedException(typeof(ArgumentNullException), ExceptionMessage= "Log Message", MatchType=MessageMatch.Contains)]

有同样的结果。

最后,鉴于我的方法使用 Path.GetFullPath(string directory),我不确定这是否被视为集成测试或单元测试。无论如何,我现在的主要问题是了解我做错了什么。 :)
非常感谢, 杰特诺。

更新:在考虑了所有要点并查看了我的系统需求后,我决定不抛出异常。相反,我决定创建测试来涵盖在我的情况下可能发生的不同可能的异常。测试方法如下:

        [Test]
    public void returns_true_for_empty_string()
    {
        var testDirectory = "";
        var sut = new DirectoryInfoValidator();
        var isInvalidPath = sut.FilePathHasInvalidChars(testDirectory);
        Assert.That(isInvalidPath, Is.True);
    }

这是一个起点。我打算通过为一个测试提供所有输入并同时检查所有输入来使用 [TestCase] 选项。谢谢你们的帮助。

【问题讨论】:

  • 您正在捕获并消除异常 -> 因此测试在第一个实例中无法正常工作。
  • @Arran 感谢您的快速回复。啊,那太傻了。有没有办法让我能够检查测试中抛出了什么异常,而不是在捕获它之后将其抛出到原始方法中?
  • 顺便说一句,您的单元测试应该与您的代码的预期功能相匹配 - 如果您希望您的方法抛出异常,则仅测试您的方法是否抛出异常。否则,请测试您想要的返回值,您将在此过程中发现意外的异常。
  • 在您的设置功能中,您可以在已知位置创建一些“虚拟”文件,在它们上测试您的各种方法,然后在您的拆卸功能中您可以摆脱它们(前提是您的方法没有'还没有)
  • 您可能会发现这篇文章很有用:msdn.microsoft.com/en-us/library/hh549175.aspx

标签: c# unit-testing exception-handling nunit integration-testing


【解决方案1】:

您的代码不会抛出ArgumentNullException。根据您的代码,它不应该*抛出任何异常 - 它应该简单地返回 truefalse

将您的测试更改为 NUnit 等效项:

Assert.IsTrue(() => sut.FilePathHasInvalidChars(testDirectory));

或者,如果空字符串应该抛出 ArgumentNullException,请将代码修改为如下内容**:

private static bool FilePathHasInvalidChars(string userInputPath)
{
    if(string.IsNullOrWhiteSpace(userInputPath) throw new
        ArgumentNullException("userInputPath");
    try
    {
        Path.GetFullPath(userInputPath);//this is where the warning appears

    }
    catch (ArgumentException e)
    {
        Log.Error(String.Format(
            "The Program failed to run due to invalid characters or empty string value for the Input Directory. Full Path : <{0}>. Error Message : {1}.",
            userInputPath, e.Message), e);
        throw;    
    }
    catch (Exception e)
    {
        Log.Error(String.Format(
            "The Program failed to run due to invalid characters or empty string value for the Input Directory. Full Path : <{0}>. Error Message : {1}.",
            userInputPath, e.Message), e);
        return true;

    }
    return false;
}

*- 对于“从不”的值,这意味着“很少你不太可能需要考虑它”

**- 我没有尝试编译,所以可能有错误;这只是一个起点。

【讨论】:

  • 嗨艾伦,非常感谢您的回答。我有 2 个正确答案。不幸的是,我不能同时标记两者。我会将马克的回答与他在几秒钟前得到的一样正确,但再次感谢你:)
【解决方案2】:

您的方法 FilePathHasInvalidChars 不会引发异常。在您的方法内部引发异常,但您的方法会捕获并处理异常。您的方法将始终返回有效值。

如果您希望您的方法抛出 ArgumentNullException 而不是记录并吞下它,请尝试以下操作:

private static bool FilePathHasInvalidChars(string userInputPath)
{
    try
    {
        Path.GetFullPath(userInputPath);//this is where the warning appears

    }
    catch (ArgumentNullException) {
        Log.Error("The Program failed to run due to a null string value for the Input Directory.");
        throw;
    }
    catch (Exception e)
    {
        Log.Error(String.Format(
            "The Program failed to run due to invalid characters or empty string value for the Input Directory. Full Path : <{0}>. Error Message : {1}.",
            userInputPath, e.Message), e);
        return true;

    }
    return false;
}

通过此修改,如果 userInputPath 为 null,您的方法将记录并重新抛出 ArgumentNullException,您的单元测试将看到异常并通过。

【讨论】:

  • 嗨,马克。感谢您的快速回复。这正是我所需要的。 :)
猜你喜欢
  • 2014-08-14
  • 2013-03-16
  • 2016-02-27
  • 2011-01-24
  • 1970-01-01
  • 2011-07-31
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多