2

過去に、次のようなデータ アクセス/リポジトリ コードを作成するときに、単純な CRUD 操作の単体テストを作成しました。

using(var connection = new WhateverConnection(connectionString))
{
    connection.Open();
    using(var transaction = connection.BeginTransaction())
    {
        try
        {
            //test the CRUD operation
        }
        finally
        {
            //gets rid of any stuff created during the test
            transaction.Rollback();
        }
    }
}

今日、私は EF4 Code First をいじっていましたが、このテスト シナリオが Entity Framework レキシコンでどのように変換されるか分からないことに気付きました。を呼び出すと、呼び出されたかどうかに関係なく、DbContext.SaveChanges()保存してAcceptAllChanges()コミットするようです。ObjectContextの代わりに を使用してもDbContext、作成されたモック/テスト オブジェクトを手動でクリーンアップしないと、この単純なテスト シナリオを再現する方法がわかりません。MSDNでこの記事を読みましたが、実際には型メソッドもTransactionScopeありません。Rollback私は使用TransactionScopeし、決して呼び出しませんかComplete? 単体テスト中にロールバックするために DbContext および/または ObjectContext を使用する別の方法または方法はありますか? EF4 Code First で TDD の考え方を完全に再調整する必要がありますか?

4

1 に答える 1

8

ObjectContextそれ自体はトランザクション動作を公開しません。自分でトランザクションで EF コードをラップする必要があります。それを行う簡単な方法は、を使用することですTransactionScopeCompleteスコープでメソッドを呼び出さずに破棄すると、ロールバックが実行されます。通常、このタイプの統合テストには基本クラスを使用します。

[TestClass]
public abstract class TransactionTestBase
{
    private TransactionScope scope = null;

    [TestInitialize]
    public virtual void TestInitialize()
    {
      scope = new TransactionScope(TransactionScopeOption.RequiresNew,
          new TransactionOptions()
              {
                  IsolationLevel = IsolationLevel.ReadUncommitted
              });
    }

    [TestCleanup]
    public virtual void TestCleanup()
    {
        if (scope != null)
        {
            scope.Dispose();
            scope = null;
        }
    }
}

すべてのテスト クラスは、このクラスから派生します。派生クラスのTestInitializeそれぞれの前に呼び出され、それぞれの後に呼び出されるため、テストはトランザクションをまったく処理する必要がありません。TestMethodTestCleanupTestMethod

于 2010-12-08T00:22:41.550 に答える