Autofixture для списка объектов, который имеет защищенный конструктор и фабричный метод

public partial class TestObjectCode
{
    /// <summary>
    /// We don't make constructor public and forcing to create object using
    /// <see cref="Create"/> method.
    /// But constructor can not be private since it's used by EntityFramework.
    /// Thats why we did it protected.
    /// </summary>
    protected TestObjectCode() {}

    public static  TestObjectCode Create(
                    DateTime executiontime,
                    Int32 conditionid,
                    String conditionname)
    {
        var @objectToReturn = new TestObjectCode
        {

            ExecutionTime = executiontime,
            ConditionId = conditionid,
            ConditionName = conditionname
        };

        return @objectToReturn;
    }

    public virtual Int32 ConditionId { get; set; }

    public virtual String ConditionName { get; set; }

    public virtual DateTime ExecutionTime { get; set; }
}

Контрольная работа:

[Test]
[TestCase("1/1/2015", "07/5/2016")]
public void Task Should_Filter_By_Date_Range_Only(string startDate, string endDate)
{
    //Arrange
    var startDateTime = DateTime.Parse(startDate);
    var endDateTime = DateTime.Parse(endDate);

    //get randomDate between two Dates
    TimeSpan timeSpan = endDateTime - startDateTime;
    var randomTest = new Random();
    TimeSpan newSpan = new TimeSpan(0, randomTest.Next(0, (int)timeSpan.TotalMinutes), 0);
    DateTime newDate = startDateTime + newSpan;

    var list = new List<TestObjectCode>();
    _fixture.AddManyTo(list);
    _fixture.Customize<TestObjectCode>(
        c => c
        .With(x => x.ExecutionTime, newDate)
        .With(x => x.ConditionId, 1)
        );
    _fixture.RepeatCount = 7;
    _fixture.AddManyTo(list);
}

Вышеприведенный тест завершается неудачно из-за того, что _fixture.Customize и мой ctor продолжают работу. если я сделаю это общедоступным, это сработает, но я хотел бы сделать его защищенным. у этого класса есть еще 15 свойств, которые я здесь не перечислил. также я хотел случайную дату между двумя dateRanges для каждого элемента в списке.

Как я могу вызвать фабричный метод Create? мне нужно определить autoFixure для каждого свойства?

Ploeh.AutoFixture.ObjectCreationException: декорированный ISpecimenBuilder не смог создать образец на основе запроса: EMR.Entities.AbpAuditLogs. Это может произойти, если запрос представляет интерфейс или абстрактный класс; в этом случае зарегистрируйте ISpecimenBuilder, который может создавать образцы на основе запроса. Если это происходит в строго типизированном выражении сборки, попробуйте указать фабрику с помощью одного из методов IFactoryComposer.


person Justin Homes    schedule 12.11.2016    source источник


Ответы (1)


Вы можете пройти вышеуказанный тест, добавив .FromFactory(new MethodInvoker(new FactoryMethodQuery())) в свою настройку:

fixture.Customize<TestObjectCode>(
    c => c
    .FromFactory(new MethodInvoker(new FactoryMethodQuery()))
    .With(x => x.ExecutionTime, newDate)
    .With(x => x.ConditionId, 1));

Оба этих класса определены в пространстве имен Ploeh.AutoFixture.Kernel.

Однако все это говорит о том, что вам следует решительно пересмотреть свой общий подход.

person Mark Seemann    schedule 12.11.2016
comment
это работает, но только первый объект в списке следует правилам настройки для _fixture.AddManyTo(list); остальные предметы случайны - person Justin Homes; 12.11.2016