如何在不违反单一责任原则的情况下编写类似的测试用例?

时间:2016-08-10 14:44:23

标签: c# unit-testing tdd solid-principles single-responsibility-principle

我为不同的输入创建了一个单元测试,以确保输出正确。

[TestMethod]
    public void CountInversionTest()
    {
        #region Arrange
        int[] sourceArray = {4, 3, 2, 1};
        int correctInversionCount = 6;
        int[] sourceArray2 = { 1, 3, 5, 2, 4, 6};
        int correctInversionCount2 = 3;
        int[] sourceArray3 = { 5, 6, 2, 3, 1, 4, 7 };
        int correctInversionCount3 = 10;
        #endregion

        #region Act
        Sorter sorter = new Sorter();
        int inversionCount = sorter.CountInversion(sourceArray);
        int inversionCount2 = sorter.CountInversion(sourceArray2);
        int inversionCount3 = sorter.CountInversion(sourceArray3);
        #endregion

        #region Assert
        Assert.AreEqual(correctInversionCount, inversionCount);
        Assert.AreEqual(correctInversionCount2, inversionCount2);
        Assert.AreEqual(correctInversionCount3, inversionCount3);
        #endregion
    }

因为案例非常相似,我把它们放在一个测试方法中。这种行为是否正常还是违反了单一责任原则?如果它打破SRP,什么是更好的解决方案?

3 个答案:

答案 0 :(得分:5)

使用适当的单元测试框架,例如xUnit.net,您可以改为编写Parameterized Test

[Theory]
[InlineData(new[] { 4, 3, 2, 1 }, 6)]
[InlineData(new[] { 1, 3, 5, 2, 4, 6 }, 3)]
[InlineData(new[] { 5, 6, 2, 3, 1, 4, 7 }, 10)]
public void ParameterizedCountInversionTest(int[] input, int expected)
{
    Sorter sut = new Sorter();
    var actual = sut.CountInversion(input);
    Assert.Equal(expected, actual);
}

这将运行三个测试,而不是一个,让您更好地了解哪个特定测试用例失败(如果失败)。

这样的测试也更具可读性。

NUnit也有此功能,但MSTest没有(我上次看过)。

答案 1 :(得分:1)

单一责任原则告诉我们,这种方法应该只有一个改变的理由。因此,单元测试应测试一种方法,并且只应在被测方法发生变化时进行更改。这就是CountInversion()方法。 CountInversion()方法是否会以这样一种方式发生变化:sourceArray输入之一必须改变而其他输入不会改变?在这种情况下,输入应分成单独的测试以适应SRP。

通常,对于一个单元测试来说,使用不同的输入多次调用被测方法是很好的。正如@ itsme86评论的那样,测试框架通常通过将参数传递给单元测试来促进这种行为。

答案 2 :(得分:1)

我决定回答我自己的问题

因为我没有使用任何第三方框架或库进行测试,而是使用默认的MSTest。 我最终做了这个

    [TestMethod]
    public void CountInversionTestCase1()
    {
        CountInversionTest(new int[] { 4, 3, 2, 1 }, 6);
    }
    [TestMethod]
    public void CountInversionTestCase2()
    {
        CountInversionTest(new int[] { 1, 3, 5, 2, 4, 6 }, 3);
    }
    [TestMethod]
    public void CountInversionTestCase3()
    {
        CountInversionTest(new int[] { 5, 6, 2, 3, 1, 4, 7 }, 10);
    }

    public void CountInversionTest(int[] sourceArray, int expectedInversionCount)
    {
        #region Act
        Sorter sorter = new Sorter();
        long actualInversionCount = sorter.CountInversion(sourceArray);
        #endregion

        #region Assert
        Assert.AreEqual(expectedInversionCount, actualInversionCount);
        #endregion
    }

这不是最好的解决方案,但它满足要求并且不使用任何第三方库。 我希望它可以帮助那里的任何人。