【问题标题】:Bogus RuleFor private field私有领域的虚假规则
【发布时间】:2021-06-09 23:17:35
【问题描述】:

我有私有只读字段的课程

        public class Bar
        {
            private readonly ICollection<Foo> somePrivateCollection = new HashSet<Foo>();
            public IEnumerable<Foo> SomePublicCollection => somePrivateCollection;

            public int z;
        }

        public class Foo
        {
            public int x;
        }

我可以通过 GetField => SetValue 设置这个字段

        [Fact]
        public void someTest()
        {
            var fooObjects = new Faker<Foo>().Generate(1);
            var barObject = new Faker<Bar>().RuleFor(t => t.z, f => f.Random.Int())
                                            .Generate();

            barObject.GetType()
                     .GetField("somePrivateCollection", System.Reflection.BindingFlags.NonPublic |
                                                                        System.Reflection.BindingFlags.Instance)
                     .SetValue(barObject, fooObjects);
        }

但是如何使用相同的样式设置此字段

            var barObject = new Faker<Bar>().RuleFor(t => t.z, f => f.Random.Int())
                                            .RuleSetter("somePrivateCollection",fooObjects)
                                            .Generate();

【问题讨论】:

  • 为什么somePrivateCollection需要直接更新?另外,为什么要创建一个假的具体类?
  • @AndrewS 用于测试目的,测试使用相同功能将项目添加到列表的功能,我认为这不是一个好主意

标签: c# unit-testing bogus


【解决方案1】:

如果公共字段和私有字段之间的区别仅在 1 个字母中

 public class PrivateBinder : Binder
    {
        public override Dictionary<string, MemberInfo> GetMembers(Type t)
        {
            var members = base.GetMembers(t);

            var privateBindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
            var allPrivateMembers = t.GetMembers(privateBindingFlags)
                                     .OfType<FieldInfo>()
                                     .Where( fi => fi.IsPrivate )
                                     .Where( fi => !fi.GetCustomAttributes(typeof(CompilerGeneratedAttribute)).Any() )
                                     .ToArray();

            foreach( var privateField in allPrivateMembers ){
                members.Add(privateField.Name, privateField);
            }
            return members;
        }
    }

public class DataFaker<T> : Faker<T> where T : class
    {
        public DataFaker(IBinder backingFieldBinder): base(binder: backingFieldBinder)
        {
        }

        public DataFaker<T> UsingPrivate()
        {
            return base.CustomInstantiator(f => Activator.CreateInstance(typeof(T), nonPublic: true) as T)
                    as DataFaker<T>;
        }

        public virtual Faker<T> RuleForPrivate<TProperty>(Expression<Func<T, TProperty>> property, TProperty value)
        {
            var propName = PropertyName.For(property);
            propName = propName.First()
                               .ToString()
                               .ToLower() +
                    propName.Substring(1);
            return AddRule(propName, (f, t) => value);
        }
    }

 var data =new DataFaker<Bar>(backingFieldBinder).UsingPrivate().RuleForPrivate(x => x.SomeCollection, value)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-06
    • 2015-07-12
    相关资源
    最近更新 更多