17

ASP.NET サイト (例: ASP.NET MVC サイト) を実行するときに、テスト永続化レイヤーを作成するためのベスト プラクティスは何ですか?

私が見た多くの例では、単体テスト プロジェクトで Moq (または別のモッキング フレームワーク) を使用していますが、永続化レイヤーを moq アウトして、Web サイトにデータなどを表示するようにしたいのですが、それはデータベースからのものではありません。それを最後にしたい。私が見たすべてのモックは、単体テストにしか存在しません。

迅速かつ迅速な開発のために永続化レイヤーを偽造 (スタブ?) したい場合、人々はどのようなプラクティスを実行しますか? 私はそれを処理するために Dependency Injection を使用し、永続化レイヤーにハードコードされた結果をいくつか持っています (これは本当に手作業で退屈です)。

他の人は何をしていますか?例とリンクは素晴らしいでしょう:)

アップデート

ちょっとした更新: これまでのところ、各クラスがインターフェイスを実装する偽のリポジトリと SQL リポジトリを使用することで、かなりの距離を稼いでいます。次に、DI (私は StructureMap を使用しています) を使用して、偽のリポジトリと SQL リポジトリを切り替えることができます。これまでのところ、うまく機能しています:)

(これを編集していたときから、ほぼ11か月前にこの質問をしたと思うと恐ろしいです!)

4

6 に答える 6

3

RobConeryのMVCストアフロントのリポジトリパターンを使用していると仮定します。

http://blog.wekeroad.com/mvc-storefront/mvc-storefront-part-1/

私はロブ・コナリーのチュートリアルに従いましたが、あなたと同じ欲求に遭遇しました。最善の方法は、作成したモックリポジトリをモックと呼ばれる別のプロジェクトに移動することです。そうすれば、サービスをインスタンス化するときに、実際のリポジトリと簡単に交換できます。冒険心があれば、設定ファイルから値を取得してモックまたは実際のリポジトリをインスタンス化するファクトリを作成できます。

例えば

public static ICatalogRepository GetCatalogRepository(bool useMock)
{
     if(useMock)
          return new FakeCatalogRepository();
     else
          return new SqlCatalogRepository();
}

または依存性注入フレームワークを使用します:)

container.Resolve<ICatalogRepository>();

幸運を!

編集:コメントに応じて、リストとLINQを使用してデータベースの操作(G​​etProducts、StoreProductなど)をエミュレートしたいようです。私は前にこれをしました。次に例を示します。

public class Product
{
     public int Identity { get; set; }
     public string Name { get; set; }
     public string Description { get; set; }
     //etc
}

public class FakeCatalogRepository()
{
     private List<Product> _fakes;

     public FakeCatalogCatalogRepository()
     {
          _fakes = new List<Product>();

          //Set up some initial fake data
          for(int i=0; i < 5; i++)
          {
              Product p = new Product
              {
                 Identity = i,
                 Name = "product"+i,
                 Description = "description of product"+i
              };

              _fakes.Add(p);
          }
     }

     public void StoreProduct(Product p)
     {
         //Emulate insert/update functionality

         _fakes.Add(p);
     }

     public Product GetProductByIdentity(int id)
     {
          //emulate "SELECT * FROM products WHERE id = 1234
          var aProduct = (from p in _fakes.AsQueryable()
                         where p.Identity = id
                         select p).SingleOrDefault();

          return aProduct;
     }
}

それはもう少し意味がありますか?

于 2008-11-13T13:47:05.600 に答える
0

私は、単体テスト クラスのセットアップ メソッド中にテーブルとデータを作成し、テストを実行してから、分解中にクリーンアップを行うというルートをたどりました。はい、この方法は機能しますが、実際にデバッグ目的で単体テストを使用することになった場合は、必ずセットアップを実行し、何かをデバッグしてから、ティアダウンを行わずに途中で停止します。これは非常に脆弱であり、(長期的には) テスト データベースに不適切なデータが含まれたり、単体テストが使用できなくなったりする可能性があります。個人的には、モッキング フレームワークを使用してデータベース レイヤーをモックするのが最善だと考えています。データベースでロジックを実行することが最善の場合があることは理解しています。このような場合、DBFitなどのツールを使用して、データベース層のテストを作成できます。

于 2008-11-13T14:46:33.950 に答える
0

私は Asp.Net や MVC フレームワークを使用していませんが、データベースにアクセスせずにサービスをテストする必要があります。あなたの質問は、私がどのようにそれを行うかについての短い(おそらくそれほど短くはない)要約の作成を引き起こしました。それが最高だと主張しているわけではありませんが、私たちにとってはうまくいきます. リポジトリを介してデータにアクセスし、必要に応じて、投稿で説明されているようにインメモリ リポジトリをプラグインします。

http://blogs.microsoft.co.il/blogs/kim/archive/2008/11/14/testable-data-access-with-the-repository-pattern.aspx

于 2008-11-14T07:46:36.013 に答える
0

SQLite と ActiveRecord を備えた完全なインメモリ データベースを使用しています。基本的に、すべての統合テストが実行される前にデータベースを削除して再作成し、データが常に既知の状態になるようにします。データベースの内容は、コードによって挿入されます。したがって、例は次のようになります。

ActiveRecord.Initalize(lots of parameters)
ActiveRecord.DropSchema();
ActiveRecord.CreateSchema();

そして、DDDスタイルで多くの顧客を追加するだけです:

customerRepository.Save(customer);

これを解決する別の方法は、NDbUnit を使用してデータベースの状態を維持することです。

于 2008-11-23T16:32:01.940 に答える
0

私はこの質問が少し古いことを知っていますが、ついに答えを思いつきました:)

まず、RavenDb (Embedded)を使用します。RavenDb Document Databaseの一部です。完全にメモリ内のデータベースであり、単体テストで完全に機能します:) MSTest、NUnit、およびxUnitで実行しました。

次に、RavenDb を使用したくない場合は、SqlLite で NHibernate を使用できます。Ayende には、この の使用に関する投稿があります。

于 2012-01-18T11:43:24.743 に答える
0

退屈であろうとなかろうと、あなたは正しい道を進んでいると思います。サービスレイヤーに注入される IRepository の具体的な実装である fakeRepository を作成していると思います。エンティティの形状とサービス、コントローラー、ビューの動作に満足した将来のある時点で、データベースを使用してそれらのエンティティを永続化する実際のリポジトリをテストできるため、これは素晴らしいことです。 . もちろん、これらのテストの性質は統合テストですが、それ以上に重要ではありません。

実際のリポジトリを作成するときに退屈しないかもしれないことの 1 つは、永続化のために nHibernate を使用する場合、エンティティの nhibernate マップを作成した後、nhibernate にデータベースを生成させることができるということです。従来のスキーマを使用する必要があります。

たとえば、db スキーマを生成するために SetUpFixture によって呼び出される次のメソッドがあります。

public class SchemaBuilder
{
   public static void ExportSchema()
    {
        Configuration configuration = new Configuration();
        configuration.Configure();
        new SchemaExport(configuration).Create(true, true);
    }
}

私のSetUpFixtureは次のとおりです。

[SetUpFixture]
public class SetUpFixture
{
    [SetUp]
    public void SetUp()
    {
        SchemaBuilder.ExportSchema();
        DataLoader.LoadData();
    }
}

ここで、DataLoader は、実際のリポジトリを使用してすべてのシード データとテスト データを作成する責任があります。

これはおそらくあなたの質問には答えませんが、あなたのアプローチを安心させるのに役立つことを願っています.

グレッグ

于 2008-11-13T14:14:16.607 に答える