xUnit.net理论,其中MemberData来自派生类

时间:2017-05-24 21:56:47

标签: c# xunit xunit.net

使用xUnit.net,Theory可能使MemberData来自派生类吗?

public abstract class BaseTest
{
    public abstract IEnumerable<object[]> Data();

    [Theory]
    [MemberData(nameof(Data))]
    public void TestData(string expected, string actual)
    {
        // assert goes here
    }
}

public class ComplexTest : BaseTest
{
    public override IEnumerable<object[]> Data()
    {
        // data goes here
    }
}

上面的代码会导致以下错误消息:

  

System.NotSupportedException:不支持指定的方法。

4 个答案:

答案 0 :(得分:4)

据我所知,这是不可能的。 MemberData的数据必须为static,因此数据必须来自其自己的类。

public static IEnumerable<object[]> Data()
{
    // data goes here
}

[Theory]
[MemberData(nameof(Data))]
public void TestData(string expected, string actual)
{
    // assert goes here
}

答案 1 :(得分:2)

你的答案是正确的。发布这个非答案,以防碰巧引发一个想法。

MemberData可以传递参数,这可能会有所帮助,具体取决于您的具体情况?

除此之外,你可以做的最好的事情是放一个货运代理:

public abstract class BaseTest
{
    protected void RunTest(string expected, string actual)
    {
        Assert.Equal(expected, actual);
    }
}

public class ComplexTest : BaseTest
{
    static IEnumerable<object[]> Data() = 
    {
        { "a", "a" }
    }

    [Theory, MemberData(nameof(Data))]
    void TestData(expected, actual) => base.RunTest(expected, actual);
}

答案 2 :(得分:2)

另一种方法(和IMO清理工具)是将测试场景放在他们自己的特定类中,并将每个场景集定义为单独的MemberData属性:

public class BaseTest
{
    [Theory]
    [MemberData(nameof(TestScenarios1.Data), MemberType = typeof(TestScenarios1)]
    [MemberData(nameof(TestScenarios1.MoreData), MemberType = typeof(TestScenarios1)]
    [MemberData(nameof(TestScenarios2.DifferentData), MemberType = typeof(TestScenarios2)]
    public void TestData(string expected, string actual)
    {
        // assert goes here
    }
}

public class TestScenarios1
{
    public static IEnumerable<object[]> Data()
    {
        // data goes here
    }

    public static IEnumerable<object[]> MoreData()
    {
        // data goes here
    }
}

public class TestScenarios2
{
    public static IEnumerable<object[]> DifferentData()
    {
        // data goes here
    }
}

答案 3 :(得分:1)

另一种方法是仅将MemberData添加到派生类。 它将按名称检查成员,并从当前类中选择正确的成员。 分析器发出的唯一警告是,您必须在基类中指定成员(默认情况下将其视为错误),因此您必须禁用此规则。如果尝试在两个类(基类和派生类)中都指定此方法,则仅使用基类。 xunit github中描述的有关分析器的问题:https://github.com/xunit/xunit/issues/1243

您的示例可能如下:

public abstract class BaseTest
{
    [Theory]
#pragma warning disable xUnit1015 // MemberData must reference an existing member
    [MemberData(nameof(Data))]
#pragma warning restore xUnit1015 // MemberData must reference an existing member
    public void TestData(string expected, string actual)
    {
        // assert goes here
    }
}

public class ComplexTest : BaseTest
{
    public static IEnumerable<object[]> Data()
    {
        return data;
        // data goes here
    }
}