2

テスト容易性を向上させるためにプロジェクトをリファクタリングしようとしています。そのため、抽象ファクトリを導入しています。

私のアプリケーションは、 を使用してさまざまなソースからデータを収集しますICrawlers。これらICrawlerはサードパーティのライブラリを使用して、Twitter などのさまざまなソースにアクセスします。

例: 私の TwitterCrawler はTweetSharpを使用して Twitter データにアクセスします。

私の最初のバージョンでは、TweetSharp クライアントを Crawler に強力に結合しました。ここで、TweetSharp を aITwitterClientと a のTweetSharpTwitterClient実装に抽象化しました。

次のステップは、sを作成するaITwitterClientFactoryを使用して aを導入することです。これにより、テスト出力を提供する を作成するファクトリに切り替えることができるため、目標 (テスト容易性) に近づくはずです。DefaultTwitterClientFactoryTweetSharpTwitterClientMockTwitterClientFactoryMockTwitterClient

では、本題に入ります。私は依存性注入にMEFを使用しています(しかし、私はそれにかなり慣れていません)。私がやっていることはこれです:

public class TwitterCrawler : CrawlerBase, ICrawler 
{
    [Import]
    public ITwitterClientFactory TwitterClientFactory {get; set;}

    public override Process()
    {
        ITwitterClient twitterClient = TwitterClientFactory.MakeSingletonClient();
        // do something with twitterClient
    }
}

私のDefaultTwitterClientFactoryMEFへのエクスポートに対して:

[Export(typeof(ITwitterClient))]
public class DefaultTwitterClientFactory: ITwitterClientFactory
{
    // implementation of ITwitterClientFactory
    // provides methods to create instances of ITwitterClient implementations
}

さて、これはこれまでのところ機能していますが、私の質問は、工場を切り替える方法ですか? 単体テストを作成し、MockClientFactory代わりに を使用するにはどうすればよいDefaultTwitterClientFactoryですか?

私のアプローチはまったく良いですか?使用するファクトリを手動で設定した方が良いですか? どこかのような

... new TwitterCrawler(mockedTwitterClientFactory)

あるいは

.... new TwitterCrawler(mockedTwitterClient)?

これは実際には問題を TwitterClient の外に移動するだけですが、それでもどこかで ITwitterClient を構築する方法と、その目的に使用するファクトリを決定する必要があります。

MEF (ExportProvider?) の仕組みをもっと掘り下げる必要がありますか?

4

1 に答える 1

3

単体テストで composer/container を使用する必要はありません。SUTTest Doublesに直接配線するだけです。

このようなもの:

var sut = new TwitterCrawler();
sut.TwitterClientFactory = new FakeTwitterClientFactory();

ただし、プロパティは依存関係がオプションであることを意味するため、プロパティ インジェクションからコンストラクタ インジェクションにリファクタリングする必要があります。

ところで、DefaultTwitterClientFactory はそれ自体をエクスポートせず、ITwitterClient をエクスポートします。

于 2011-05-03T09:57:48.530 に答える