2009-08-10 4 views
2

私たちはASP.NET MVCサイトを構築していますが、私は単体テストを有効にするための接続を定義する場所に苦労しています(私は '接続'を一般的に使用します - セッション、接続、アダプタ、トランザクションおよびデータベース操作を管理することができる他のタイプのデータコンテキスト)。MVCでデータ・コンテキスト(アダプタ、接続、セッションなど)をインスタンス化する場所は?

のは、我々は3つのクラスがあるとしましょう:過去には

UserController 
UserService 
UserRepository 

を、私たちはUserServiceの方法の中にこのような何かをしたい:

Using (ISomeSession session = new SomeSession()) 
{ 
    session.StartTransaction(); 
    IUserRepository rep = new UserRepository(session); 
    rep.DoSomething(); 
    rep.Save(); 
    session.Commit(); 
} 

しかし、それは本当にありませんでしたSomeSessionへの依存性が注入されなかったため、これをユニットテストすることが可能です。しかし、D.I. UserServiceに依存関係を挿入するには、UserServiceの存続期間中にセッションがハングアップします。 UserControllerから呼び出された複数のサービスがある場合、UserControllerがガベージコレクションされるまで、各サービスがハングアップしている可能性があります。

これをよりうまく管理する方法についてのご意見はありますか?私は明白な何かを欠いていますか

編集

申し訳ありませんが、私は明確ではなかった場合 - 私はセッション/データコンテキストと依存性注入を使用することができることを理解し、しかし、それは、サービスクラスの寿命にわたって維持されています。実行時間の長いアクション/メソッド(つまり、バッチプロセスによってサービスが呼び出されているとします)では、テスト可能性を追加する以外の理由でオープンセッションが多く発生する可能性があります。

+1

実際の接続でテストしている場合、単体テストではなく統合テストです。 – RichardOD

+0

リチャード - 私はそれを理解しています。私の主張は、クラスの生存期間を通じて、接続ステートメントを使用している間に、接続ステートをクラスレベルまで動かす(または少なくともコンテキストをアクティブにする)ことなく、依存関係をどのように移動するかを知りませんでした。 「使用する」ブロックは、必要に応じて接続を開き、完了したら接続を閉じるので、はるかに安全です。 –

答えて

2

RichardODが正しく観察されるため、ユニットテストの作成にライブデータベース接続を使用することはできません。あなたがそれをしているなら、あなたは統合テストです。

私は、私のリポジトリインタフェース、1つの実際のリポジトリ、1つのユニットテスト用の1つの偽のリポジトリ用に別々の実装をしています。偽のリポジトリは、実際のデータコンテキストではなくジェネリックリストで動作します。私は、正しいリポジトリを注入するために、DIを使っています(物事をより快適にするためには、Ninjectを使用しますが、手動でもできます)。

実際の接続で単体テストしているインスタンスはごくわずかですが、これはコントローラ、UI、ビジネスレイヤオブジェクトではなく、自分のリポジトリクラスの単体テストです。

編集:あなたが追加したコメントで、私はあなたが実際に求めていたことを理解したと思います。私は先週、非常に同じテーマで作業していたので面白いと思います。

非常に薄いラッパーの中でデータコンテキストをインスタンス化し、そのコンテキストをHttpContext.Current.Items辞書の中に入れます。このように、コンテキストはグローバルですが、現在の要求に対してのみです。

まだ、質問の件名は誤解を招くほどです。あなたは「ユニットテストのためのデータコンテキストをどこでインスタンス化するか」と尋ねていました。答えはあなたが通常はしないということです。私の単体テストはまだ偽のリポジトリで動作しています。

+0

あなたがダウンボートしても大丈夫ですが、なぜそうなのか説明するといいです... –

+0

申し訳ありませんが...私は応答すべきでした。あなたの答えは正しいですが、それは私の質問に答えなかったので私はそれをdownvoted。私はD.I.を理解する。偽のリポジトリを作成する方法について説明します。問題は、コンテキストがリポジトリの外で定義され、他のサービス/リポジトリクラスに渡すことができる(つまり、トランザクションに参加できるようにする)ことです。サービスのコンテキスト(または注入)でコンテキスト/接続をインスタンス化すると、コンテキストの寿命はサービスのものと同じになります...本質的に、接続状態を典型的な "Using(new context) {...} " –

+0

ああ、大丈夫です。上記の私の編集を参照してください... –

-2

最も簡単な方法は、web.configで開発と生産のために定義するConnectionstringを用意することです。 Unittestの場合は、Testプロジェクトのapp.configで定義します。

関連する問題