从第三方库自动固定创建类,该类具有无法访问的内部构造函数

时间:2019-07-10 13:14:34

标签: autofixture

我想使用Autofixture创建我从第3方库使用的类的实例。

我面临的问题是此类的构造函数具有内部访问修饰符,并且从第三方解决方案中我无法真正使用InternalsVisibleTo属性,因此我想知道是否可以使用任何Autofixture行为或在这种情况下是否可以应用其他替代技术。

public class RecordedEvent
  {
    /// <summary>The Event Stream that this event belongs to</summary>
    public readonly string EventStreamId;
    /// <summary>The Unique Identifier representing this event</summary>
    public readonly Guid EventId;
    /// <summary>The number of this event in the stream</summary>
    .....

    internal RecordedEvent(....)
    {
      .....
    }
  }

1 个答案:

答案 0 :(得分:2)

OOTB,AutoFixture试图找到能够创建类实例的公共构造函数或静态工厂方法。由于您不拥有RecordedEvent且无法添加公共构造函数,因此您必须教导 AutoFixture如何实例化它。有一种叫做Customizations的机制可以用于此目的。

首先,您创建一个自定义,它能够找到该类型的所有内部构造函数:

public class InternalConstructorCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customize<RecordedEvent>(c =>
            c.FromFactory(
                new MethodInvoker(
                    new InternalConstructorQuery())));
    }

    private class InternalConstructorQuery : IMethodQuery
    {
        public IEnumerable<IMethod> SelectMethods(Type type)
        {
            if (type == null) { throw new ArgumentNullException(nameof(type)); }

            return from ci in type.GetTypeInfo()
                    .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)
                   select new ConstructorMethod(ci) as IMethod;
        }
    }
}

然后将其应用于您的Fixture

var fixture = new Fixture()
    .Customize(new InternalConstructorCustomization());

,然后您可以创建RecordedEvent类的实例:

var recordedEvent = fixture.Create<RecordedEvent>(); // does not throw