15

Pex&Molesを使用する人はそれほど多くないので、これは難しい問題だと思います(Pexは本当に素晴らしい製品ですが、他のどの単体テストツールよりもはるかに優れています)

エンティティが1つだけの非常に単純なモデルを持つデータプロジェクトがあります(DBItemDBRepositoryこのプロジェクト内で、この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 Explorationsを実行しましたが、エラーパスの境界を超えました。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スタブを使用する必要がありますか?Molesホストが実行されるように、テストメソッドに属性を追加する必要がありますか(現在実行されているかどうかはわかりません)。私はPex&Molesだけを実行しています。VSテストやnUnitなどはありません。

この特定のテスト方法で提供するアイテムの数に、おそらくPexに制限を設定する必要があると思います。

4

3 に答える 3

5

Molesは、外部依存関係(ファイルアクセス、ネットワークアクセス、データベースアクセスなど)を持つアプリケーションの部分をテストするようには設計されていません。代わりに、Molesを使用すると、アプリのこれらの部分をモックして、外部依存関係のない部分で真の単体テストを実行できます。

したがって、EFオブジェクトとクエリをモックする必要があると思います。たとえば、メモリ内リストを作成し、クエリメソッドに、関連する基準に基づいてそれらのリストから偽のデータを返すようにします。

于 2010-11-12T04:16:17.857 に答える
0

私はちょうどpexにも慣れてきています...私の問題は私がmoqでそれを使いたいと思っていることを取り囲んでいました;)

とりあえず ...

同じ問題を抱えているあなたに似た方法がいくつかあります。私が最大値を上げると、彼らは去りました。おそらくペックスは、枝を十分に探索したことに満足していました。コードコントラクト検証のタイムアウトも増やす必要があるメソッドがあります。

ただし、おそらく支配すべきことの1つは、すべての依存オブジェクトをパラメーターとして渡すことです。つまり、メソッドでリポジトリをインスタンス化せずに、渡します。

あなたが抱えている一般的な問題は、メソッドで大きなオブジェクトをインスタンス化していることです。私は自分のDALクラスでも同じことをしていますが、それらを個別に単体テストしようとはしていません。データセットを作成し、これを使用してデータアクセスコードをテストします。

私はビジネスロジックとオブジェクトにpexを使用しています。

DALコードIDをテストしようとすると、IOCを使用してデータコンテキストをメソッドに渡す必要があります。これにより、データコンテキストをモックできるため、テストが可能になります。

于 2010-10-04T12:20:32.053 に答える
0

Entity Frameworkリポジトリパターンを使用する必要があります:http://www.codeproject.com/KB/database/ImplRepositoryPatternEF.aspx

于 2010-11-06T16:33:50.383 に答える