一尘不染

将复杂的参数传递给[理论]

c#

Xunit具有一个不错的功能:您可以创建一个带有Theory属性的测试,然后将数据放入InlineData属性中,而xUnit将生成许多测试并将其全部测试。

我想有这样的事情,但参数我的方法不是“简单的数据”(如stringintdouble),但我的类的列表:

public static void WriteReportsToMemoryStream(
    IEnumerable<MyCustomClass> listReport,
    MemoryStream ms,
    StreamWriter writer) { ... }

阅读 202

收藏
2020-05-19

共1个答案

一尘不染

xxxxDataXUnit中有许多属性。例如查看PropertyData属性。

您可以实现返回的属性IEnumerable<object[]>object[]然后,此方法生成的每个参数都将被“解包”为单个调用[Theory]方法的参数。

另一个选项是ClassData,它的工作原理相同,但是可以轻松地在不同类/名称空间中的测试之间共享“生成器”,并且还可以将“数据生成器”与实际测试方法分开。

从此处查看这些示例

PropertyData示例

public class StringTests2
{
    [Theory, PropertyData(nameof(SplitCountData))]
    public void SplitCount(string input, int expectedCount)
    {
        var actualCount = input.Split(' ').Count();
        Assert.Equal(expectedCount, actualCount);
    }

    public static IEnumerable<object[]> SplitCountData
    {
        get
        {
            // Or this could read from a file. :)
            return new[]
            {
                new object[] { "xUnit", 1 },
                new object[] { "is fun", 2 },
                new object[] { "to test with", 3 }
            };
        }
    }
}

ClassData示例

public class StringTests3
{
    [Theory, ClassData(typeof(IndexOfData))]
    public void IndexOf(string input, char letter, int expected)
    {
        var actual = input.IndexOf(letter);
        Assert.Equal(expected, actual);
    }
}

public class IndexOfData : IEnumerable<object[]>
{
    private readonly List<object[]> _data = new List<object[]>
    {
        new object[] { "hello world", 'w', 6 },
        new object[] { "goodnight moon", 'w', -1 }
    };

    public IEnumerator<object[]> GetEnumerator()
    { return _data.GetEnumerator(); }

    IEnumerator IEnumerable.GetEnumerator()
    { return GetEnumerator(); }
}
2020-05-19