c# - 将复杂参数传递给 [Theory]

标签 c# unit-testing xunit xunit.net

Xunit has a nice feature : 你可以创建一个带有 Theory 属性的测试并将数据放入 InlineData 属性中,xUnit 将生成许多测试,并测试它们。

我想要这样的东西,但是我的方法的参数不是“简单数据”(比如 stringintdouble),而是我类(class)的列表:

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

最佳答案

有很多xxxxData XUnit 中的属性。查看例如 MemberData属性。

您可以实现一个返回 IEnumerable<object[]> 的属性.每个object[]此方法生成的结果将被“解压”为一次调用您的 [Theory] 的参数。方法。

参见即 these examples from here

这里有一些例子,只是为了快速浏览。

MemberData 示例:就在手边

public class StringTests2
{
    [Theory, MemberData(nameof(SplitCountData))]
    public void SplitCount(string input, int expectedCount)
    {
        var actualCount = input.Split(' ').Count();
        Assert.Equal(expectedCount, actualCount);
    }
 
    public static IEnumerable<object[]> SplitCountData => 
        new List<object[]>
        {
            new object[] { "xUnit", 1 },
            new object[] { "is fun", 2 },
            new object[] { "to test with", 3 }
        };
}

XUnit < 2.0:另一个选项是 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(); }
}

XUnit >= 2.0: 而不是 ClassData ,现在有一个 [MemberData] 的“重载”,允许使用来自其他类的静态成员。下面的示例已更新为使用它,因为 XUnit < 2.x 现在已经很古老了。 另一个选项是 ClassData ,它的工作原理相同,但允许在不同类/命名空间的测试之间轻松共享“生成器”,并将“数据生成器”与实际测试方法分开。

MemberData 示例:看看那里的另一种类型

public class StringTests3
{
    [Theory, MemberData(nameof(IndexOfData.SplitCountData), MemberType = 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[]>
{
    public static IEnumerable<object[]> SplitCountData => 
        new List<object[]>
        {
            new object[] { "hello world", 'w', 6 },
            new object[] { "goodnight moon", 'w', -1 }
        };
}

免责声明:)

上次在 C# 5.0 和 xunit 2.4.1 上使用 dotnetfiddle.net 检查 @20210903 ..但失败了。我不能将测试运行器混入那个 fiddle 。但至少它编译得很好。请注意,这最初是几年前写的,有些变化。我根据我的直觉和评论修复了它们。所以..它可能包含不明显的拼写错误,否则会在运行时立即弹出明显的错误,以及牛奶和坚果的痕迹。

关于c# - 将复杂参数传递给 [Theory],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51540009/

相关文章:

c# - 如何从具有连接表的数据库动态创建 WPF 窗口?

asp.net-core - 如何从单元测试访问 IApplicationEnvironment?

code-coverage - .net核心项目代码覆盖率Visual Studio 2017

c# - 为什么LinqPad返回 The name 'ModelName' does not exist in the current context 错误?

c# - MD5文件处理

html - 自动化测试CSS和HTML前端编码

c# - 对象关于单元测试的状态

java - 为什么 TestNG 允许几个预期的异常?

c# - 对方法的每个输出进行单独的单元测试

c# - 如何从服务器读取多个文件到c#