1

まず、この質問のオープンエンドの性質についてお詫び申し上げます。しかし、私はこれで何ヵ月も麻痺していますが、同意調査にもかかわらず、これを逃すことはできません。テスト可能なMVC3&EF 4.1アプリケーションを構築する

私はしばらくの間、MVC/EFアプリケーションで作業しています。私はEntity Framework(4.1)がサポートするテスト可能なMVC3アプリケーションを設計して構築する方法を理解しようとしています。件名herehere、およびhereについて、私が尋ねたいくつかの質問を見ることができます。

私はそれを複雑にしないようにしようとしていますが、私はそれが成長することができる、ゆるく結合したデザインであることを望んでいます。

MVCアプリこれは非常に薄いある
:以下、私はそれを理解する方法は、かなりの最低限必要なコンポーネントです。可能な限り小さなロジックがここにあります。私のビューはできるだけ条件付きロジックが少なく、ビューモデルはPOCO以上のものではなく、コントローラは単にビューモデルとドメインモデルの間のマッピングを処理し、サービスに呼び出すだけです。私のビジネスロジックのすべてが行く場所です

サービス層+インタフェース(別のアセンブリ)
。これの目的は、アプリケーションの中身を公開するために、シンクライアント(フォームアプリ、モバイルアプリ、Webサービス)をこれに加えて打つことができるようにすることです。サービスレイヤのインターフェイスは、別のアセンブリにあります。

コアユーティリティ/横断+インターフェース(別個のアセンブリ)
これは私は私のアプリケーションに固有ではないビルドものであるが、フレームワークまたは私が使用しているサードパーティのプラグインの一部ではありません。ここでも、これらのコンポーネントへのインターフェイスは、それぞれのアセンブリにあります。

リポジトリ(EFコンテキスト)
これは私のドメインモデルと私のデータベース間のインタフェースです。私のサービス層はこれを使用して、ドメインモデルを介してデータベースを検索/変更します。

ドメインモデル(EF POCOS)
EF4はPOCOSを生成しました。これらのいくつかは

(例えばOrder.Total = Order.Details.Sum(d => d.Price)など)他のネストされたプロパティまたは計算されたプロパティへの便宜のために延長することができるIoCコンテナ
これはMVCに私の偽/コンクリートの依存関係(サービス/ユーティリティ)を注入するために使用されるものですアプリ&サービス。コンストラクタインジェクションは、一貫して使用されます。私は苦労してるのはここ

は次のとおりです。

1)統合テストは、ユニットテスト対が適切です。例えば、いくつかのアセンブリは両方の組み合わせを必要とするか、MVCアプリケーションのための統合テストと私のサービス&ユーティリティのユニットテストですか?

2)リポジトリ/ドメインモデルコードに対してテストを書くのは苦労しますか?もちろん、POCOの場合、これは適用されません。しかし、計算されたプロパティを持つPOCOを拡張するとどうなりますか?

3)リポジトリに使用する適切なパターン。私はこれが非常に主観的であることを知っています。これが議論されるたびに誰もが異なるアプローチをしているようです。したがって、どの方法を使うのか把握することが難しくなります。たとえば、自分のリポジトリをロールするか、EF(DbContext)を直接使用するだけですか?

4)私のサービスのテストを書くとき、私は自分のリポジトリをモックするのですか、あるいはSQL Liteを使って模擬データベースを構築し、テストしますか? (討議herehereを参照)。

5)これは、全くテストしても、すべてをテストする必要がありますか?それとも、テストの問題はテストなしより優れていますか?後者の場合、より重要な領域が最初にヒットする部分はどこですか(私はサービスレイヤーを考えています)。

6)これらの質問のほとんどに答えるのに役立つ良い本、記事、サンプルアプリがありますか?

今は十分だと思います。これが終わりすぎると、私に知らせてください。私は喜んで閉じます。しかし、もう一度、私は何ヶ月もかけて、これを自分自身で考えてみようと何もしなかった。

答えて

5

これは本当に複雑な質問です。

  1. 統合テストとユニットテストがお互いを置き換えるものではありません:私は唯一の短い要約を記述しますので、あなたのポイントは、それぞれ別々の問題であることが十分な大きさです。十分にテストされたアプリケーションが必要な場合は、常に両方が必要です。単体テストはロジックを孤立して(通常モック、スタブ、フェイクなどの助けを借りて)テストしますが、統合テストはコンポーネントが正しく動作するかどうかをテストするためのテストです(モック、スタブ、偽物はありません)。いつ統合テストを使用するか、単体テストを使用するかは、実際にテストしているコードと、あなたが従っている開発アプローチ(例えば、TDD)によって決まります。

  2. POCOにロジックが含まれている場合は、ユニットテストを作成する必要があります。リポジトリのロジックはデータベースに大きく依存しているので、データベースを使わずにコンテキストをモックしてテストすると、通常は役に立たないので、統合テストでそれらをカバーする必要があります。

  3. これは本当にリポジトリからの期待に依存しています。それが愚かなDbContext/DbSetラッパーである場合、リポジトリの値は0であり、参照されているいくつかの議論で説明されているように、あなたのコードユニットをテスト可能にすることはほとんどありません。クエリをラップすると(上位レイヤにLINQ-to-entitesはない)、集約ルートへのアクセスを公開すると、リポジトリの意味はデータアクセスの正確な分離とモック可能なインターフェイスの公開です。

  4. これは前の点に完全に依存しています。 IQueryableを公開するか、Expression<Func<>>を受け入れる方法がIQueryableに内部である場合はyou cannot correctly mock the repository(ただし、各ユニットテストと同じロジックをテストする統合テストとペアリングする必要があります)。 LINQ-to-entitiesは「副作用」/漏れ抽象です。リポジトリ内でクエリを完全にラップし、独自の宣言型クエリ言語(仕様パターン)を使用すると、それらをモックできます。

  5. すべてのテストはテストしない方が良いです。多くの方法論では、高密度カバレッジが必要です。テストは常に最初に書き込まれ、テストなしではロジックが存在しないため、TDDは100%テストカバレッジにもなります。それは、あなたが従っている方法論と、コードのテストを必要とするかどうかを専門的に決めるまでです。

  6. 「これを読んで、それを行う方法を知っている」とは思いません。これはソフトウェア工学であり、ソフトウェア工学はアートです。あらゆる場合に機能する青色のプリントはありません(ほとんどの場合ではありません)。

+0

ありがとう、Ladislav。私はこれが簡単な質問ではないことを知っています、とにかくそれを刺していただきありがとうございます。明確にするために、私はおそらくダムのリポジトリを持ち、LINQとエンティティのロジックをサービスレイヤに保持しています。だから、実際には私のサービス層に多くの責任(ビジネス+クエリロジック)を置くことになるでしょう。これは独自の問題につながりますか?つまり、LINQとエンティティのロジックのリポジトリを持ち、サービスレイヤを厳密なビジネスロジックに保つことと比べて、これとのトレードオフは何ですか?再び、私はこれが主観的であることを知っています、私はトレードオフを理解していることを確認しようとしています。 –

+0

_話題にならないように、SOコミュニティへの貢献、特に私の質問に感謝したいと思います。多くの場合、私の質問にたくさん答えるように思われます。時間と思考の部分。それは評価されません。 –