Autofixture создать класс из сторонней библиотеки, которая имеет недоступный внутренний конструктор - PullRequest
0 голосов
/ 10 июля 2019

Я хотел бы использовать Autofixture для создания экземпляра класса, который я использую из сторонней библиотеки.

Проблема, с которой я сталкиваюсь, состоит в том, что конструктор этого класса имеет внутренний модификатор доступа, и, будучи сторонним решением, я не могу действительно использовать атрибут 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 Ответ

2 голосов
/ 10 июля 2019

OOTB, AutoFixture пытается найти общедоступные конструкторы или метод статической фабрики, который может создать экземпляр класса. Поскольку у вас нет RecordedEvent и вы не можете добавить открытый конструктор, вам нужно научить автофиксированию, как его создавать. Для этого можно использовать механизм Настройки .

Прежде всего, вы создаете настройку , которая может найти все внутренние конструкторы для типа:

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
...