Настройка конструктора AutoFixture с использованием свойства seed - PullRequest
16 голосов
/ 23 марта 2011

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

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

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

спасибо

  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();
  }

1 Ответ

29 голосов
/ 23 марта 2011

Прежде чем я углублюсь в ответы на конкретные вопросы, я хотел бы отметить кое-что, что может быть намного проще: вы могли бы рассмотреть вопрос о назначении значений для этих доступных для записи свойств после того, как вы вызвали 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, но я склонен использовать вышеописанную технику, потому что обычный .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());

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

НТН

...