Подтвердить что ты не робот

Настройка автостроителя AutoFixture с засеянным имуществом

У меня есть настраиваемый автозапуск для интеграционного теста. Код ниже.

Вопрос 1 - В настоящее время первая транзакция имеет TransactionViewKey.TransactionId из 1 и т.д. Как установить TransactionViewKey TransactionId, чтобы он был выровнен из метода param beginTransactionId? например, возвращая массив TransactionView, где первый TransactionId равен 200, а затем каждый увеличивается на 1?

Вопрос 2 - лямбда для определения transactiondate, кажется, выполняется только один раз - и поэтому каждая дата имеет одно и то же значение. Как настроить построитель, чтобы он запускал генератор случайных дат для каждого сгенерированного экземпляра, а не только один раз?

спасибо

  static TransactionView[] CreateTransactions(int transactionsToReturnCount, long beginningTransactionId) {
      Random random = new Random();
      IFixture fixture = new Fixture();
      fixture.Customize<TransactionViewKey>(ob => ob
                                    .With(t => t.TransactionId)
                                    .With(t => t.TransactionIdSpecified, true)
                                    .OmitAutoProperties()
                                    );
      fixture.Customize<TransactionView>(ob => ob
                                             .With(t => t.TransactionDate, DateTime.Now - new TimeSpan(random.Next(30),0,0,0))
                                             .With(t => t.PostDate, DateTime.Now - new TimeSpan(random.Next(30), 0, 0, 0))
                                             .With(t => t.ViewKey)
                                             .With(t => t.Amount)
                                             .OmitAutoProperties()
          );
      IEnumerable<TransactionView> transactionViews = fixture.CreateMany<TransactionView>(transactionsToReturnCount);
      return transactionViews.OrderBy(t => t.TransactionDate).ToArray();
  }
4b9b3361

Ответ 1

Прежде чем я начну отвечать на конкретные вопросы, я хотел бы указать на что-то, что может быть намного проще: вы могли бы просто назначить значения этим записываемым свойствам после вызова CreateMany, но перед возвратом результата.

Что-то вроде этого:

var transactionViews = fixture.CreateMany<TransactionView>(transactionsToReturnCount);
foreach (var tv in transactionViews)
{
    tv.ViewKey.TransactionId = beginningTransactionId++;
    tv.TransactionDate = DateTime.Now - new TimeSpan(random.Next(30),0,0,0);
}
return transactionViews.OrderBy(t => t.TransactionDate).ToArray();

Это может выглядеть как взломать, но на самом деле это не так. AutoFixture предназначен для создания Анонимных значений, поэтому всякий раз, когда вы пытаетесь назначить определенные значения (которые вы сейчас используете), вы выходите за пределы своей первоначальной цели.

Не поймите меня неправильно: здорово, что вы используете AutoFixture, как это. Мне также иногда приходится назначать некоторые конкретные значения некоторым членам экземпляров, которые я создаю AutoFixture, но я склонен использовать вышеупомянутый метод, потому что обычный .NET API геттеров и сеттер уже специализируется на выполнении именно этого. С другой стороны, AutoFixture специализируется на определении правил для неопределенности, поэтому его цель противоположна.

Тем не менее, я сказал, что теперь я отвечу на конкретные вопросы, изложенные выше:

Вопрос 1

Я не пытался скомпилировать это, так что вам, возможно, придется немного подкорректировать его, но самое лучшее, что вы можете сделать, это что-то вроде этого:

fixture.Customize<TransactionViewKey>(ob => ob
    .Without(t => t.TransactionId)
    .Do(t => t.TransactionId = beginningTransactionId++)
    .With(t => t.TransactionIdSpecified, true)
    .OmitAutoProperties());

Вопрос 2

Второй параметр метода With не является делегатом - это значение, поэтому он оценивается только один раз.

Чтобы оценить его каждый раз, вы можете использовать тот же трюк, что и выше:

fixture.Customize<TransactionView>(ob => ob
    .Without(t => t.TransactionDate)
    .Do(t => t.TransactionDate = DateTime.Now - new TimeSpan(random.Next(30),0,0,0))
    .With(t => t.PostDate, DateTime.Now - new TimeSpan(random.Next(30), 0, 0, 0))
    .With(t => t.ViewKey)
    .With(t => t.Amount)
    .OmitAutoProperties());

Пожалуйста, дайте мне знать, если у вас есть дополнительные вопросы.

НТН