2009-09-21 34 views
3

私は最近、特別なフォーマットのファイルからデータベースにデータをインポートするためのシンプルなユーティリティを作成するタスクを持っています。私は少数のクラス(プログラムクラスはビジネスロジッククラスで動作し、ビジネスロジッククラスはデータアクセスクラスで動作する)でコンソールアプリケーションを実装しました。すべてがうまくいきますが、今では単体テストやリファクタリングアプリケーションを作成することを考えています(これまでの単体テストを作成していないので、このアプリケーションは練習には最適なフィールドだと思います) 。データアクセス、ユニットテスト、依存性注入

これは問題です:データアクセスクラスが静的にされていますが、これを模擬して結果として実際の単体テストを作成することはできません。これを修正するには、インターフェイスを作成してデータアクセスクラスに実装する必要があります。また、ビジネスロジッククラスにそのインターフェイスタイプのパラメータを受け入れるコンストラクタを追加する必要があります。これは、アプリケーションのMain()メソッドでデータアクセスクラスを作成することになりますが、これが最善の方法ではないことがわかります(エントリポイントがデータアクセスに関するいくつかのことを知っていなければならないのでしょうか?はるかに長いか、いくつかの鎖があるはずですか?)。私はいくつかのIoCコンテナを使用することができますが、これはコンテナを使用するには単純すぎるアプリケーションだと思います。

ありがとうございます!代わりに、直接データアクセスクラスあなたを呼び出す、使用ヘルパーメソッド:

public void insert (...) { 
     DataAccess.insert (...); 
    } 

今、あなたはこれらの呼び出しを無効にすることができます。ここ

答えて

5

私はインターフェイスを作成し、データアクセスクラスでそれを実装する必要があります。また、 というコンストラクターをビジネスロジッククラスに追加する必要があります。 そのインターフェイスのパラメーターを受け入れる タイプです。だから、これは私が アプリケーションのmain()メソッドでは、データアクセスクラスを作成 を終了することを意味し、 何かがこのない最高の アプローチは( エントリポイントがいくつか データアクセスの事について知っておくべきこと、それは本当にokです私に指示します?チェーン がはるかに長い場合、または いくつかのチェーン?)逆に

がどうあるべきか!このは、少なくともテスト容易性の観点からは、最良のアプローチであるです。

ビジネスロジック層をテスト可能にする唯一の方法は、あなたが熟考していることを正確に行うことによってデータアクセス層からデータを分離することです。

あなたの最上位レベルのアプリケーションは、バック・ストップが停止する部分です。具体的なデータ・アクセス・クラスが何であるかを知る必要がある唯一のコンポーネントです。

チェーンがかなり長い場合やチェーンが複数ある場合は、それほど大したことはありません(ただし、アプリケーションレイヤが壊れてしまった場合、一部のアプリケーションレイヤを折りたたむことを検討することをお勧めします)。

public CustomerView() { 
    IRespository  repository  = new ConcreteRepository(); 
    IAccountingService accountingService = new ConcreteAccountingService(repository); 
    ICustomerService customerService = new ConcreteCustomerService(accountingService, repository) 
    this._Presenter = new CustomerPresenter(customerService); 
} 

PresenterRepositoryに依存し、(またRepositoryに依存する)AccountingServiceに依存しているCustomerService依存性を有し、Model-View-PresenterアプリのViewでこの潜在的なコードを検討最後に、依存性注入コンテナを使用する必要はありません(そのうちのいくつかは驚くほど軽量ですが)。手作業による依存性注入は、自分自身を繰り返し繰り返し始めるまでうまく動作します(または、実行時の依存関係)。

+0

+1:ニースの答え!私は特に、「どこが止まったのか」という行が好きです。DIコンテナに関する良いコメントもあります。 – TrueWill

+0

@ジェフ - ありがとう、私はそれを試してみましょう。私の悲観的な存在は私にいくつかの隠された落とし穴があるはずだと言っています:) – Dev

+0

@Dev:懐疑主義は敬虔の次です! ;) –

0

はシンプルなソリューションです。私はそうのようなテストを分割することをお勧め:

  1. は、それが右のパラメータを取得するときにDataAccessは正しいことをやっていることを確認してくださいテストのカップルを作成します。

  2. モックアップテストでは、に送信されたパラメータを収集するだけです。 DataAccessには一切電話しないでください。 #1で

テストでは、#2でのテストは、あなたが正しい値でDataAccessを呼び出していることを確認する一方DBへのデータの書き込みが動作することを確認します。後者のテストは非常に迅速に実行され、特別なケースなどをテストするのが容易になります。

いつも#1からテストを実行する必要はありません。 DataAccessまたはリリース前に何かを変更した場合のみ。これは、効率的で快適なテストを行います。

+0

答えとしてコメントを追加しましたが、あまりスペースがありませんでした – Dev

+0

@Dev - 答えに応答すると非常に混乱することがあります。最終的に答えは並べ替えられ、Aaronは彼の名前を変えるかもしれないし、彼は彼の答えを削除するかもしれない。コメントに答えることをお勧めします。割り当てられた文字よりも余裕が必要な場合は、2つのコメントに回答を広めることができます。また、元の質問を編集して、人々があなたに答えるのに役立つと思われる場合は、情報の一部を含めることができます。 –

+0

ありがとうございました。ジェフは、その "答え"をコメントに移します。 – Dev

1

LINQ to SQLを使用していると仮定すると、おそらくレポジトリパターンを使用してDataContextを後でモックできるインターフェイスにラップすることができるため、ユニットテストが可能になります。

は、ここでは一つであり、インターネットの周りにこのテーマに関するいくつかの記事があります。 http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx

+0

今私は、ファイルから読み込んでファイルに書き込むためのカスタムメソッドを持つ型付きデータセットを使用しています。エンティティ・フレームワークやlinq2sqlを最初に使用しませんでした。なぜなら、このアプリケーションを作成しなければならなかったので、私が経験していないテクノロジの実験にはあまり時間がなかったからです。しかし、これは良いアイデアです。 DAL。 – Dev