使用私人nunit测试不要重复自己

时间:2017-08-01 10:39:15

标签: c# unit-testing nunit

我是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<object> testDelegate = () => _import.LoadBatchFile(path);

测试是否抛出ArgumentNullException

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

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

3 个答案:

答案 0 :(得分:4)

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

[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

答案 1 :(得分:1)

我建议您使用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;
    }

有关详细信息,请参阅有关TestCaseSource

documentation

答案 2 :(得分:0)

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

[TestCase(" ")]

你已经完成了。