2011-01-19 11 views
4

実際にデータに影響を与えずにデータベースにストアドプロシージャのテストをいくつか実行したい(または、テストの実行後に永続的な影響を与えることなく) 。DBユニットテストでTransactionScCommunicationExceptionが発生する

は、いくつかの研究の後、私は、私は単一のテストメソッド内でこのすべてを置くよう今これは罰金限り動作します私のVisual Studio 2010のテストプロジェクトなど

using(new TransactionScope()) 
{ 
    using(SqlConnection connection = new SqlConnection("someConnectionString")) 
    { 
     connection.Open(); 
     using(SqlCommand command = new SqlCommand("some sql", connection)) 
     { 
      // Do some database stuff... 
     } 
    } 
} 

内のTransactionScopeを使用してのアプローチを思い付いつまり、TransactionScopeの使用ブロックが終了すると、データベースに対するすべての変更は自動的にロールバックされます。

私の問題は、ClassInitializeでデータベースの処理をしたいので、テストクラスごとに1回だけ行う必要があります。共有のTransactionScopeプロパティを作成し、ClassInitializeメソッドでTransactionScopeのインスタンスを割り当てると、これは問題なく動作します。テストメソッドのいずれかでデータベース関連の処理を行うと、そのメソッド内でTransactionManagerCommunicationExceptionが発生します。

私はそれが事実であることをよく理解していませんし、私のアプローチに間違いがあるかどうか、あるいはすべてのセットを含むTransactionScopeをセットアップする必要なしに、各テストメソッド内のテスト用のテスト用のコンポーネントを再度作成します。

以下のコードの抜粋

EDITが、私はこれが十分な情報を与える願っています:

public TransactionScope Scope { get; set; } 

[ClassInitialize] 
public static void ClassInitialize(TestContext testContext) 
{ 
    Scope = new TransactionScope(); 
    // Do some db set up stuff, e.g. create records used for tests etc. 
} 

[ClassCleanup] 
public static void ClassCleanup() 
{ 
    Scope.Dispose(); 
} 

[TestMethod] 
public void MyTestMethod() 
{ 
    using(SqlConnection connection = new SqlConnection("someConnectionString")) 
    { 
     DataTable result = new DataTable(); 
     using(SqlCommand command = new SqlCommand("spName", connection)) 
     { 
      command.CommandType = CommandType.StoredProcedure; 
      using(SqlDataAdapter adapter = new SqlDataAdapter()) 
      { 
       adapter.SelecteCommand = command; 
       // The next line causes the exception to be thrown 
       adapter.Fill(result); 
      } 
     } 

     // Assertions against DataTable result 
    } 
} 

例外が


TransactionManagerCommunicationExceptionあるユーザーコードによって分散のための ネットワークアクセス未処理でしたトランザクションマネージャ(MSDTC)が無効になっています。コンポーネントサービスの管理ツールを使用して、MSDTCのセキュリティ構成でネットワークアクセス用のDTCを有効にしてください。


私は設定を試してみて、変更される可能性があることを理解し、私は例外で始まることを得るなぜ私は理解していない - シングル(テスト)の方法では、上記のコードを持つと比べて異なるが何でありますか?可能性、あなたが取得しているエラーについては

void Main() 
{ 
    using(new SetupTransaction()) 
    { 
    //Your test 
    } 
} 

public class SetupTransaction : IDisposable 
{ 
    private TransactionScope transaction; 

    public SetupTransaction() 
    { 
     transaction = new TransactionScope(); 
     //Do your stuff here 
    } 

    public void Dispose() 
    { 
     transaction.Dispose(); 
    } 
} 

:事前に

おかげで、

よろしく

G.

+0

例外から詳細を提供できますか? –

答えて

4

例外として、MSDTCが有効になっていません。私は、あなたが個別にTransactionScopeを使用していたときには、DTCを必要としないローカルSQLトランザクションを作成していただけだと思います。ただし、複数の接続を介してTransactionScopeを共有すると、DTCを通じてトランザクションが分散トランザクションに「昇格」されますが、これは有効化されていない可能性があります。

ローカルマシンとサーバー上のMSDTCでネットワークアクセスを有効にしてください。これを行う手順は、お使いのOSによって少し異なります。 Here's how to do it in Win 2003 ServerHere's a link for Win 2008。ファイアウォールを介してDTCを有効にする必要があることに注意してください(最後のリンクで説明されています...)

+0

これは正しい方向に私を指摘してくれました。複数の接続を開いたときに例外が発生したので、別のメソッドから再利用できるPublic Connectionプロパティを作成しました。 私がコードを変更したときに知ったことは、クリーンアップメソッドでInvalidOperationExceptionを回避する方法でした。作成するコールを移動して、[TestInitialize]と[TestCleanup]でマークされたメソッドにTransactionScopeをディスパッチする必要がありました等価クラス。 – Gorgsenegger

0

あなたは、このようなセットアップの何かを作成することができます実装をどのように使っているのか正確に投稿しますか?

0

私が成功裏に使用したアプローチの1つは、セットアップとティアダウンを実装する基本クラスを作成することです。セットアップメソッドでは、新しいトランザクションスコープを作成し、それをプライベートクラス変数に格納します。ティアダウンメソッドでは、トランザクションスコープをロールバックします。

私はNUNitを使用していますが、原則はMSTestと同じである必要があります。ここでのヒントは、とTearDownの前後に1回ずつ実行されていることです。ユニットテスト間の分離を確実にするために、それぞれユニットテストが行​​われます。

また、@ blechには、このソリューションが機能するためには、Microsoft分散トランザクションコーディネータ(MSDTC)サービスが実行されている必要があります。

+0

ご返信ありがとうございます。しかし、このアプローチは、1つの(セットアップ)メソッドでTransactionScopeを起動し、別の(テスト)メソッドを呼び出して、それをクリーンアップ(ティアダウン)で破棄するときに、同じ問題で終了しませんか? NUnitに相当するのは、ClassInitialize(TestFixtureSetup)とTestInitialize(SetUp)と対応するTearDown対応クラス(ClassCleanup、TestCleanup)です。 – Gorgsenegger

+0

@Gorgsenegger - おそらく。 'TestInitialize'と' TestCleanup'を使ってテストしましたか? –

+0

@Peter Lillevold私は、基本クラスでのトランザクションの使用と現在のテストクラスでの直接使用の違いを理解していませんでした。コードの再利用や何か他のことについて話していますか? – satyajit

関連する問題