【问题标题】:Use a private nunit test to don't repeat myself使用私人 nunit 测试不要重复自己
【发布时间】:2017-08-01 10:39:15
【问题描述】:

我是 TDD 开发的新手,刚刚开始使用 Nunit 3.7.1、C# 和 .NET Framework 4.7 进行一些测试。

我有这个测试类:

[TestFixture]
class ProcessTrzlExportTest
{
    private ImportTrzlBatch _import;

    [SetUp]
    public void SetUpImportTrzlBatch()
    {
        _import = new ImportTrzlBatch();
    }

    [Test]
    public void ShouldThrowArgumentExceptionWithNullPath()
    {
        // Arrange
        string path = null;

        // Act
        ActualValueDelegate<object> testDelegate = () => _import.LoadBatchFile(path);

        // Assert
        Assert.That(testDelegate, Throws.TypeOf<ArgumentNullException>());
    }

    [Test]
    public void ShouldThrowArgumentExceptionWithEmptyPath()
    {
        string path = string.Empty;

        // Act
        ActualValueDelegate<object> testDelegate = () => _import.LoadBatchFile(path);

        // Assert
        Assert.That(testDelegate, Throws.TypeOf<ArgumentNullException>());
    }

    [Test]
    public void ShouldThrowArgumentExceptionWithWhiteSpacesPath()
    {
        string path = " ";

        // Act
        ActualValueDelegate<object> testDelegate = () => _import.LoadBatchFile(path);

        // Assert
        Assert.That(testDelegate, Throws.TypeOf<ArgumentNullException>());
    }
}

要测试这个类:

public class ImportTrzlBatch
{
    public object LoadBatchFile(string path)
    {
        if (string.IsNullOrWhiteSpace(path))
            throw new ArgumentNullException(nameof(path));

        return null;
    }
}

我正在测试path 不为空、空或空白。我有三种测试方法可以用三种不同的输入来测试同一种方法。

我可以使用私有测试方法不重复代码并从这三个不同路径的三个方法中调用它吗?

另一个问题是我正在使用这个:
ActualValueDelegate&lt;object&gt; testDelegate = () =&gt; _import.LoadBatchFile(path);

测试是否抛出ArgumentNullException

是否有另一种方法可以在不使用委托的情况下测试是否抛出异常?

顺便说一句,我已经复制了代码以检查它是否从这个 SO 答案中抛出 ArgumentNullExceptionhttps://stackoverflow.com/a/33897450/68571

【问题讨论】:

  • 你的意思是使用Assert.Throws&lt;&gt;()还是Assert.DoesNotThrow&lt;&gt;()
  • 我不知道。我已经从这个 SO 答案中复制了 Assert.Thatstackoverflow.com/a/33897450/68571
  • 你不应该在同一篇文章中问两个问题。

标签: c# unit-testing nunit


【解决方案1】:

对于这些场景,我倾向于使用 TestCase(见下文)。像这样,您只编写一次测试,只需指定要测试的不同值。在您的情况下为空字符串。

[TestCase(null)]
[TestCase("")]
public void ShouldThrowArgumentException(string path)
{
    // Act
    ActualValueDelegate<object> testDelegate = () => _import.LoadBatchFile(path);

    // Assert
    Assert.That(testDelegate, Throws.TypeOf<ArgumentNullException>());
}

您可以像这样内联委托:

[TestCase(null)]
[TestCase("")]
public void ShouldThrowArgumentException(string path)
{
    Assert.That(() => _import.LoadBatchFile(path), Throws.TypeOf<ArgumentNullException>());
}

有关 TestCase 功能的更多详细信息,请查看此文档here

【讨论】:

    【解决方案2】:

    我建议您使用TestCaseSourceAttribute,您可以将所有输入案例放入一个实现IEnumerable 的对象中,然后针对该对象调用您的测试。所以它看起来像这样:

        [TestCaseSource(nameof(ShouldThrowArgumentSource))]
        public void ShouldThrowArgumentException(string path)
        {
            // Act
            ActualValueDelegate<object> testDelegate = () => _import.LoadBatchFile(path);
    
            // Assert
            Assert.That(testDelegate, Throws.TypeOf<ArgumentNullException>());
        }
    
        private static IEnumerable ShouldThrowArgumentSource()
        {
            yield return string.Empty;
            yield return null;
        }
    

    更多详情可以阅读documentationTestCaseSource

    【讨论】:

      【解决方案3】:

      测试代码与任何其他代码一样。如果抽象一些东西是有意义的,那就去做吧。不过,在你的情况下,你赢的并不多。我认为 Cedric Royer-Bertrand 的解决方案看起来很漂亮。只需添加

      [TestCase(" ")]
      

      你就完成了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-06
        • 1970-01-01
        • 2010-09-19
        • 1970-01-01
        • 2010-11-01
        • 2014-07-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多