类级别的XUnit理论数据,而不是方法级别

7
  1. 我使用XUnit来运行C#代码中的单元测试。
  2. 我有许多抽象的单元测试类,这些类需要一个比标准XUnit测试类设置更为复杂的参数。
  3. 该参数的值来自某个静态列表(为了简化例子)。
  4. 我需要运行所有相关的单元测试类,对于该列表中可能的所有参数值,并且不需要重复的样板代码

从某种意义上说,这相当于TheoryData,但是应用于测试类的级别,而不是方法的级别。在当前的XUnit框架中是否可能?如果是,那么怎么做呢?

2个回答

3
您可以按照此处提到的方式使用 ClassData 来完成:这里
您需要创建一种类似如下的生成器类,并使用 Theory 中的 ClassData fixture。
public class TestDataGenerator : IEnumerable<object[]>
{
    private readonly List<object[]> _data = new List<object[]>
    {
        new object[] {5, 1, 3, 9},
        new object[] {7, 1, 5, 3}
    };

    public IEnumerator<object[]> GetEnumerator() => _data.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class ParameterizedTests
{
    public bool IsOddNumber(int number)
    {
        return number % 2 != 0;
    }

    [Theory]
    [ClassData(typeof(TestDataGenerator))]
    public void AllNumbers_AreOdd_WithClassData(int a, int b, int c, int d)
    {
        Assert.True(IsOddNumber(a));
        Assert.True(IsOddNumber(b));
        Assert.True(IsOddNumber(c));
        Assert.True(IsOddNumber(d));
    }
}

1
是的,谢谢。我有这个想法。这需要在每个测试类的每个测试方法上装饰这个类数据属性。这违反了DRY原则,也禁止在需要时向某些测试添加一些有用的理论数据。一个解决方案可能是在类级别应用一些自定义属性,然后在某个基类的构造函数中“展开”以获取参数列表,然后在每个测试中使用foreach。不幸的是,这将不会让xUnit识别所有这样的测试为不同的。 - Konstantin Konstantinov
1
同意,我认为这只是现有工具的限制。最终我做了类似于你所说的事情,然后添加了一个自定义记录器来收集xunit无法识别的测试结果。 - Ywapom

1
你可以使用IClassFixture。创建一个定制的 TFixture 来将数据返回给测试类构造函数。
namespace Xunit
{
    public interface IClassFixture<TFixture> where TFixture : class
    {
    }
}

你的方法应该继承自定义的装置

public class ParameterizedTests: IClassFixture<TFixture>
{
    public ParameterizedTests(TFixture fixture)
    {
    }

    public bool IsOddNumber(int number)
    {
        return number % 2 != 0;
    }

    [Theory]
    [ClassData(typeof(TestDataGenerator))]
    public void AllNumbers_AreOdd_WithClassData(int a, int b, int c, int d)
    {
        Assert.True(IsOddNumber(a));
        Assert.True(IsOddNumber(b));
        Assert.True(IsOddNumber(c));
        Assert.True(IsOddNumber(d));
    }
}

1
TestDataGenerator 定义在哪里? - Robin Salih
Fixture只是在测试之间共享数据,他想要的是如何对测试类进行参数化,而不是方法。 - Marco Pelegrini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接