2

質問

この「コンテキスト外」テストの影響をロールバックできるように、トランザクションスコープの接続を指定する方法はありますか?

バックグラウンド

RestSharp を使用して WebAPI コントローラーをテストしています。これは統合テストであり、リクエストを API に送信することによってテストを行います。このリクエストは、リポジトリとサービス レイヤーを介してデータ レイヤーに至るまで伝播します。つまり、これは意図的に単体テストではありません。

このテストは、restClient のインスタンスを作成します。

    [TestInitialize()]
    public virtual void TestInitialize()
    {

        _client = new RestClient("http://localhost:24144");
        _client.CookieContainer = new System.Net.CookieContainer();

    }

次にクライアントは、データ コンテキストをまったく知らずに (これもまた意図的に) いくつかの要求を行います。

 // pseudocode
 _client.DoThis();
 _client.DoThat();

このテストは、EF コード ファーストの移行から生成されたテスト データベースに対して実行されます。空のシード メソッドがあるため、データベースは空です。

    protected override void Seed(TestAppDbContext context)
    {
        SqlConnection.ClearAllPools();
        context.Database.Delete();
        context.Database.CreateIfNotExists();
    }

問題

これは、実行したい多くのテストの 1 つにすぎません。現在、テスト間でデータベースをドロップ/再作成し、他のテストの後に Api テストが実行されるようにする必要があります。それはデータ コンテキストについて何も知らないので、すべてのテスト コードをトランザクションにラップしてロールバックすることはできません (またはその方法を理解できませんでした)。

私が試したこと

  • TestInitialize で transactionscope を新規作成し、TestCleanup で破棄します。これは何もしません。
  • このテストの後に「update-database」を実行していますが、ClearAllPools() への呼び出しにもかかわらず、「現在使用中のため、データベースを削除できません」というメッセージが常に表示されます。これは私が注目したい問題ではありませんが、言及する価値があると思いました。
4

2 に答える 2

1

TransactionScope数か月前に同様の問題に遭遇しましたが、あなたが述べたのと同じ理由の多くを使用して、適切な解決策を思いつきませんでした.

テストプロジェクトでWebAPIをセルフホスティングすることになりました。また、各テストの実行前に削除および再作成 (および移行) できる SQLCE 4 データベースを使用します。これはしばらくの間稼働しており、非常にうまく機能しています。

于 2013-05-05T21:23:07.350 に答える
0

IsolationLevel.RepeatableRead を使用して、いくつかの統合テストを実行することができました。

ただし、API を介したエンティティの更新を含むテストは成功しませんでした。まだ完璧な解決策を探しています。

デビッドの答えのように、テストごとに新しいデータベースファイルをコピーすることは、これまでのところ完全に機能する唯一のソリューションですが、パフォーマンスには多くの要望が残されています。特に、データベース スキーマが古く、テストごとに移行/シードする必要がある場合。

NUnit のコード例:

[SetUp]
public void TestSetUp()
{
    _transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() {IsolationLevel = IsolationLevel.RepeatableRead, Timeout = TimeSpan.FromSeconds(5)});
}

[TearDown]
public void TestTearDown()
{
    // Roll back any changes made, per test.
    _transactionScope.Dispose();
}
于 2013-05-20T17:44:02.933 に答える