4

数週間前、私は MEF (ComponentModel) の流行に飛び乗り、今では多くのプラグインや共有ライブラリに使用しています。全体として、私の側の頻繁な間違いを除けば、それは素晴らしいものでした.

とにかく、私のアプリは問題なく動作していますが、MEF 関連のコード変更により、自動ビルドが失敗しました。テストしていたモジュールが MEF によって読み込まれる必要がある他のモジュールに依存していたという単純な理由で、単体テストのほとんどが失敗していました。MEF をバイパスし、これらのオブジェクトを直接インスタンス化することで、これらの状況を回避しました。

言い換えれば、MEFを介して次のようなものになります

[Import]
public ICandyInterface ci { get; set; }

[Export(typeof(ICandyInterface))]
public class MyCandy : ICandyInterface
{
    [ImportingConstructor]
    public MyCandy( [Import("name_param")] string name) {}
    ...
}

しかし、私の単体テストでは、私はただ使用します

CandyInterface MyCandy = new CandyInterface( "Godiva");

さらに、CandyInterface にはデータベースへの接続が必要ですが、単体テスト フォルダーにテスト データベースを追加するだけで回避でき、NUnit ですべてのテストにそれを使用します。

さて、この状況に関する私の質問は次のとおりです。

  1. これは悪い方法ですか?
  2. [セットアップ]でパーツを組むことをお勧めしますか?
  3. 単体テストでモックを使用する方法をまだ学習していません。これは、基礎となるデータベース接続を (何らかの方法で) モックして、ダミー データを返すだけで、実際にはデータベースを必要としない場合の良い例ですか?
  4. 以前にこのようなことに遭遇したことがある場合は、その経験と問題を解決した方法を教えていただけますか? (または、これをコミュニティ wiki に入れる必要がありますか?)
4

3 に答える 3

10

あなたは正しい軌道に乗っているように聞こえます。単体テストはunitをテストする必要があり、それはインスタンスを直接作成するときに行うことです。MEF にインスタンスを作成させると、それらは統合テストに向かう傾向があります。統合テストに問題があるというわけではありませんが、単体テストは各ユニットを分離してテストするため、より保守しやすい傾向があります。

単体テストでインスタンスを接続するためにコンテナーは必要ありません

一般的なフィクスチャのアンチパターンにつながるため、SetUp でフィクスチャを作成しないことをお勧めします。

依存関係をTest Doublesに置き換えるのがベスト プラクティスです。動的モックは、これを行うためのより用途の広い方法の 1 つなので、間違いなく学ぶべきものです。

于 2010-05-18T07:39:51.237 に答える
0

MEF を使用した単体テスト (nunit ではなく、同じように機能します) の実行方法についてブログに書きました。秘訣は MockExportProvider を使用することで、すべてのテストを継承するためのテスト ベースを作成しました。

これは、統合と単体テストで機能する私の主な AutoWire 関数です。

protected void AutoWire(MockExportProvider mocksProvider, params Assembly[] assemblies){

CompositionContainer container = null;

var assCatalogs = new List<AssemblyCatalog>();

foreach(var a in assemblies)
{
    assCatalogs.Add(new AssemblyCatalog(a));
}

if (mocksProvider != null)
{
    var providers = new List<ExportProvider>();

    providers.Add(mocksProvider); //need to use the mocks provider before the assembly ones            

    foreach (var ac in assCatalogs)
    {
        var assemblyProvider = new CatalogExportProvider(ac);                    
        providers.Add(assemblyProvider);
    }

    container = new CompositionContainer(providers.ToArray());

    foreach (var p in providers) //must set the source provider for CatalogExportProvider back to the container (kinda stupid but apparently no way around this)
    {
        if (p is CatalogExportProvider)
        {
            ((CatalogExportProvider)p).SourceProvider = container;
        }
    }
}
else
{
    container = new CompositionContainer(new AggregateCatalog(assCatalogs));
}

container.ComposeParts(this);        
}

私の投稿の詳細: https://yoavniran.wordpress.com/2012/10/18/unit-testing-wcf-and-mef/

于 2012-10-18T20:45:14.023 に答える
0

DOC を手動で作成する方が、インポートを満たすために MEF コンポジション コンテナーを使用するよりもはるかに優れていることに同意しますが、「セットアップでフィクスチャを合成すると、一般的なフィクスチャ アンチ パターンが発生する」というメモに関しては、常にそうであるとは限らないことに言及したいと思います。

静的コンテナーを使用していて、CompositionInitializer.SatisfyImports を介してインポートを満たす場合、CompositionInitializer.Initialize を複数回呼び出すことができないため、一般的なフィクスチャ アンチ パターンに直面する必要があります。ただし、いつでも CompositionContainer を作成し、カタログを追加し、コンテナー自体で SatisyImportOnce を呼び出すことができます。その場合、すべてのテストで新しい CompositionContainer を使用して、共有/一般的なフィクスチャ アンチ パターンに直面することから逃れることができます。

于 2010-11-03T15:28:06.870 に答える