18

統合テスト用にカスタマイズされた自動フィクスチャ ビルダーがあります。コードは以下です。

質問 1 - 現在、最初のトランザクションの TransactionViewKey.TransactionId は 1 などです。TransactionViewKey の TransactionId を設定して、メソッド パラメータの beginTransactionId からシードされるようにするにはどうすればよいですか? たとえば、最初の TransactionId が 200 で、それぞれが 1 ずつ増加する TransactionViews の配列を返しますか?

質問 2 - transactiondate を決定するためのラムダは 1 回だけ実行されるように見えるため、各日付は同じ値です。一度だけではなく、生成されたインスタンスごとにランダム日付ジェネレーターを実行するようにビルダーをセットアップするにはどうすればよいですか?

ありがとう

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

1 に答える 1

30

具体的な質問に答える前に、もっと簡単なことを指摘したいと思います。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 の getter と setter は既に正確にそれを行うことに特化しているため、上記の手法を使用する傾向があります。一方、AutoFixture はあいまいなルールを定義することに特化しているため、その目的は逆です。

とはいえ、ここで、上記の特定の質問に答えます。

質問1

私はこれをコンパイルしようとはしていないので、少し調整する必要があるかもしれませんが、できる最善のことは次のようなものです:

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

質問2

With メソッドの 2 番目のパラメーターはデリゲートではありません。これはであるため、一度だけ評価されます。

毎回評価するには、上記と同じトリックを使用できます。

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

于 2011-03-22T22:30:39.857 に答える