内省生成的 xUnit 通用理论

xUnit generic theories generated by introspection

我想为一些实现给定接口的 class 动态生成理论。

此时,我使用内省来获取实现的类型classes:

IEnumerable<Type> srvTypes = typeof(BaseService<>).Assembly.GetTypes()
    .Where(p => typeof(IBaseService).IsAssignableFrom(p) && !p.IsAbstract);
IEnumerable<IBaseService> srvs = srvTypes.Select(st => Activator.CreateInstance(st));

然后我可以运行服务的每个方法,如果它没有引发异常,我认为测试正常:

Assert.All(srvs, srv => srv.GetX());
Assert.All(srvs, srv => srv.DoY());
Assert.All(srvs, srv => srv.SyncZ());

对于这些线路,我只会得到 3 个测试结果,但我希望每个服务有一个。

有没有办法告诉 xUnit 运行 对每个实现 class 进行测试?

注意:我不想在理论属性中写每个 class 名称,它应该是动态的。

您可以使用您的反射代码作为理论的数据源:

public interface ICanDoX
{
    bool DoX();
}

public class A : ICanDoX
{
    public bool DoX() => true;
}

public class B : ICanDoX
{
    public bool DoX() => false;
}

public class ImplementorTests
{
    public static TheoryData<ICanDoX> Implementors;

    static ImplementorTests()
    {
        var instances = typeof(ICanDoX).Assembly.GetTypes()
            .Where(t => typeof(ICanDoX).IsAssignableFrom(t) && !t.IsAbstract)
            .Select(t => (ICanDoX)Activator.CreateInstance(t));
        Implementors = new TheoryData<ICanDoX>();
        foreach (var instance in instances)
            Implementors.Add(instance);
    }

    [Theory]
    [MemberData(nameof(Implementors))]
    public void DoX_Succeeds(ICanDoX icandox)
    {
        Assert.True(icandox.DoX());
    }
}

在测试结果中,您将对每个实施 class 进行记录,如下所示: