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

问题描述 投票:0回答:3
  1. 我使用 XUnit 在 C# 代码中运行单元测试。
  2. 我有许多抽象单元测试类,它们采用一个标准的额外相当复杂的参数(与标准 XUnit 测试类设置相比)。
  3. 该参数的值来自某个静态列表(为了示例简单起见)。
  4. 我需要为该列表中参数的所有可能值运行所有相关的单元测试类,并且无需重复的样板代码

从某种意义上来说,这相当于

TheoryData
,但应用于测试类级别而不是方法级别。这在当前的 XUnit 框架内可能吗?如果是的话,具体如何?

c# xunit xunit.net
3个回答
3
投票

您可以使用 here

提到的 ClassData 来完成此操作

您创建如下所示的某种 Generator 类,并将 ClassData 夹具与 Theory 一起使用。

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
投票

您可以使用IClassFixture。创建自定义 TFixture 以将数据返回到测试类构造函数。

namespace Xunit
{
    public interface IClassFixture<TFixture> where TFixture : class
    {
    }
}

并且你的方法应该继承自定义的fixture

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));
    }
}

0
投票

看起来继承应该可以解决这个问题:

public sealed class TestData { }
public abstract class BaseMyTests
{
    protected abstract TestData Data { get; }

    [Theory]
    [InlineData(1, 2)]
    [InlineData(5, 100)]
    public void Test1(int x, int y)
    {
        //...
    }

    [Fact]
    public void Test2()
    {
        //...
    }
}

public sealed class Group1Tests : BaseMyTests
{
    protected override TestData Data { get; } = new();
}

public sealed class Group2Tests : BaseMyTests
{
    protected override TestData Data { get; } = new();
}
© www.soinside.com 2019 - 2024. All rights reserved.