【问题标题】:xUnit generic theories generated by introspection内省产生的 xUnit 泛型理论
【发布时间】:2021-04-14 12:37:28
【问题描述】:

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

这时候,我使用自省来获取实现类的类型:

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 为每个实现类运行测试?

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

【问题讨论】:

    标签: c# generics xunit


    【解决方案1】:

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

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

    在测试结果中,您将有每个实现类的记录,如下所示:

    【讨论】:

    • 听起来不错,但我只得到一个测试结果,您是否选中了特殊选项以查看内部测试?
    • 或者附加扩展?我在 VisualStudio 2019 Preview 上,没有针对 xUnit 的特定扩展。
    • @sinsedrix 我的屏幕截图来自 Resharper “单元测试会话”窗口。基本的 VS 测试资源管理器在树中显示一个条目,在测试详细信息窗格中显示多个结果。
    猜你喜欢
    • 2017-01-26
    • 2014-07-25
    • 2016-07-25
    • 2018-10-14
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    相关资源
    最近更新 更多