【问题标题】:Collection size from attribute for Autofixture declarative autodata parameter来自 Autofixture 声明性自动数据参数的属性的集合大小
【发布时间】:2021-08-15 04:41:38
【问题描述】:

如何使用 Autofixture 的声明性参数样式传递给测试的属性上的属性指定列表/可枚举的长度/大小?

我希望能够在不将参数移动到测试主体中的情况下通过此测试。

        [Theory, AutoData]
        public void CollectionSizeTest(
            List<int> defaultSize,
            List<int> customSize,
            List<int> customSize2,
            IEnumerable<string> empty
        )
        {
            Assert.Equal(3, defaultSize.Count);
            Assert.Equal(5, customSize.Count);
            Assert.Equal(6, customSize2.Count);
            Assert.Empty(empty);
        }

【问题讨论】:

    标签: c# unit-testing autofixture


    【解决方案1】:

    您可以为此创建一个自定义属性,例如这个CollectionSizeAttribute

            [Theory, AutoData]
            public void CollectionSizeTest(
                List<int> defaultSize,
                [CollectionSize(5)] List<int> customSize,
                [CollectionSize(6)] List<int> customSize2,
                [CollectionSize(0)] IEnumerable<string> empty,
                List<string> defaultSize2
            )
            {
                Assert.Equal(3, defaultSize.Count);
                Assert.Equal(5, customSize.Count);
                Assert.Equal(6, customSize2.Count);
                Assert.Empty(empty);
                Assert.Equal(3, defaultSize2.Count);
            }
    
            public class CollectionSizeAttribute : CustomizeAttribute
            {
                private readonly int _size;
    
                public CollectionSizeAttribute(int size)
                {
                    _size = size;
                }
    
                public override ICustomization GetCustomization(ParameterInfo parameter)
                {
                    if (parameter == null) throw new ArgumentNullException(nameof(parameter));
    
                    var objectType = parameter.ParameterType.GetGenericArguments()[0];
    
                    var isTypeCompatible =
                        parameter.ParameterType.IsGenericType
                        && parameter.ParameterType.GetGenericTypeDefinition().MakeGenericType(objectType).IsAssignableFrom(typeof(List<>).MakeGenericType(objectType))
                    ;
                    if (!isTypeCompatible)
                    {
                        throw new InvalidOperationException($"{nameof(CollectionSizeAttribute)} specified for type incompatible with List: {parameter.ParameterType} {parameter.Name}");
                    }
    
                    var customizationType = typeof(CollectionSizeCustomization<>).MakeGenericType(objectType);
                    return (ICustomization) Activator.CreateInstance(customizationType, parameter, _size);
                }
    
                public class CollectionSizeCustomization<T> : ICustomization
                {
                    private readonly ParameterInfo _parameter;
                    private readonly int _repeatCount;
    
                    public CollectionSizeCustomization(ParameterInfo parameter, int repeatCount)
                    {
                        _parameter = parameter;
                        _repeatCount = repeatCount;
                    }
    
                    public void Customize(IFixture fixture)
                    {
                        fixture.Customizations.Add(new FilteringSpecimenBuilder(
                            new FixedBuilder(fixture.CreateMany<T>(_repeatCount).ToList()),
                            new EqualRequestSpecification(_parameter)
                        ));
                    }
                }
            }
    

    这会通过调用fixture.CreateMany&lt;T&gt;(_repeatCount) 将参数创建为具有给定大小的列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 2017-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多