使用种子属性自定义AutoFixture构建器

时间:2011-03-22 21:48:30

标签: c# autofixture

我有一个定制的自动混合构建器用于集成测试。代码如下。

问题1 - 目前第一个事务的TransactionViewKey.TransactionId为1,等等。如何设置TransactionViewKey TransactionId,使其从方法param beginningTransactionId 中播种?例如,返回第一个TransactionId为200的TransactionViews数组,然后每个递增1?

问题2 - 用于确定transactiondate的lambda似乎只运行一次 - 因此每个日期都是相同的值。如何设置构建器以便为每个生成的实例运行随机日期生成器而不是仅运行一次?

感谢

  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 个答案:

答案 0 :(得分:29)

在我深入回答具体问题之前,我想指出一些可能更容易的事情:可能考虑在调用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旨在创建Anonymous Values,因此无论何时尝试分配特定值(您当前都是这样),您都会超越其原始目的。

不要误会我的意思:你使用像这样的AutoFixture很酷。我有时也必须为我有AutoFixture创建的标本的某些成员分配一些特定值,但我倾向于使用上述技术,因为getters和setter的正常.NET API已经专门用于完成< / strong>即可。另一方面,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());

如果您有任何其他问题,请与我们联系。

HTH

相关问题