エンティティフレームワークを備えた「PEXおよびMOLES」ライブラリを使用する方法は?
-
04-10-2019 - |
質問
これは難しいものです あまりにも多くの人がPex&Molesなどを使用していないためです(Pexは本当に素晴らしい製品だと思います - 他のどのユニットテストツールよりもはるかに優れています)
私は持っています データ たった1つのエンティティを持つ非常にシンプルなモデルを備えたプロジェクト(DBItem
)。私も書いた DBRepository
このプロジェクトでは、このEFモデルを操作します。リポジトリには呼ばれるメソッドがあります GetItems()
これは、ビジネスレイヤーアイテムのリストを返します(BLItem
)そして、これに似ているように見えます(単純化された例):
public IList<BLItem> GetItems()
{
using (var ctx = new EFContext("name=MyWebConfigConnectionName"))
{
DateTime limit = DateTime.Today.AddDays(-10);
IList<DBItem> result = ctx.Items.Where(i => i.Changed > limit).ToList();
return result.ConvertAll(i => i.ToBusinessObject());
}
}
そのため、この特定の方法の単体テストを作成したいと思います。私は使用しています PEX&MOLES. 。 EFオブジェクトのコンテキスト用にモルとスタブを作成しました。
パラメーター化された単体テストを書きたいと思います(最初に本番コードを書いたことは知っていますが、PEX&Molesをテストしているので、この方法が有効なアイテムのリストを返すことをテストします。
これは私のテストクラスです:
[PexClass]
public class RepoTest
{
[PexMethod]
public void GetItemsTest(ObjectSet<DBItem> items)
{
MEFContext.ConstructorString = (@this, name) => {
var mole = new SEFContext();
};
DBRepository repo = new DBRepository();
IList<BLItem> result = repo.GetItems();
IList<DBItem> manual = items.Where(i => i.Changed > DateTime.Today.AddDays(-10));
if (result.Count != manual.Count)
{
throw new Exception();
}
}
}
それから私は走ります PEX探索 この特定のパラメータ化された単体テストのために、しかしエラーが発生します パス境界を超えました. 。 PEXは、提供することによりこのテストを開始します null
このテスト方法(SO items = null
)。これはコードであり、PEXが実行されています。
[Test]
[PexGeneratedBy(typeof(RepoTest))]
[Ignore("the test state was: path bounds exceeded")]
public void DBRepository_GetTasks22301()
{
this.GetItemsTest((ObjectSet<DBItem>)null);
}
これはPEXから提供された追加のコメントでした:
テストケースはこれらの入力に対してあまりにも長く実行され、PEXは分析を停止しました。注意:oblivious.data.test.repositories.taskrepositorytest.b__0のメソッドは50回呼び出されました。コードが無限のループや再帰に閉じ込められていないことを確認してください。それ以外の場合は、「MaxStack = 200」をクリックして、PEXを再度実行します。
属性を更新[pexmethod(maxstack = 200)
質問
私はこれを正しい方法でやっていますか?代わりにefcontextスタブを使用する必要がありますか?テスト方法に追加の属性を追加する必要があるように、モールホストが実行されるようにする必要がありますか(今はわかりません)。私はPex&Molesだけを走っています。 VSテストやヌニットなどはありません。
おそらく、この特定のテスト方法に提供すべきアイテムの数をPEXに設定する必要があると思います。
解決
Molesは、外部依存関係(ファイルアクセス、ネットワークアクセス、データベースアクセスなど)を持つアプリケーションの部分をテストするようには設計されていません。代わりに、Molesを使用すると、アプリのこれらの部分をモックすることで、外部依存関係がない部品で真の単体テストを行うことができます。
したがって、たとえば、EFオブジェクトやクエリをock笑するだけだと思います。たとえば、メモリ内リストを作成し、クエリメソッドに関連する基準に基づいてそれらのリストから偽のデータを返します。
他のヒント
私はただペックスを把握しているだけです...私の問題はMOQでそれを使いたいと思っていました;)
とりあえず ...
同じ問題を抱えているあなたと同様の方法がいくつかあります。私がマックスを増やしたとき、彼らは去りました。おそらく、Pexは枝を十分に調査したことに満足したと思われます。コード契約検証のタイムアウトも増やさなければならなかった方法があります。
おそらくあなたがドイーンであるべきだと思うべきことの1つは、すべての従属オブジェクトをパラメーターとして渡すことです...つまり、メソッドのレポをインスタンス化しないでください。
一般的な問題は、メソッドに大きなオブジェクトをインスタンス化していることです。私はDALクラスでも同じことをしますが、それから私はそれらを単独でユニットテストしようとしていません。データセットを構築し、これを使用してデータアクセスコードをテストします。
私はビジネスロジックとオブジェクトでPEXを使用しています。
DALコードIDをテストしようとする場合は、IOCを使用してDataContextをメソッドに渡す必要があります。これにより、データコンテキストをモックできるようにテストが可能になります。
エンティティフレームワークリポジトリパターンを使用する必要があります。 http://www.codeproject.com/kb/database/implrepositorypatternef.aspx