MEF и заводская модель - PullRequest
2 голосов
/ 03 мая 2011

Я пытаюсь реорганизовать свой проект, чтобы улучшить тестируемость, поэтому я представляю абстрактную фабрику.

Мое приложение собирает данные из разных источников с помощью ICrawlers. Эти ICrawler используют сторонние библиотеки для доступа к различным источникам, таким как, например, щебет.

Пример. Мой TwitterCrawler использует TweetSharp для доступа к данным Twitter.

Моя первая версия сильно связывала клиент TweetSharp с Crawler. Теперь я абстрагировал TweetSharp до ITwitterClient и TweetSharpTwitterClient реализации.

Следующий шаг - ввести ITwitterClientFactory с DefaultTwitterClientFactory, который создает TweetSharpTwitterClient s. Это должно приблизить меня к моей цели (тестируемости), потому что я могу переключить фабрику на MockTwitterClientFactory, который создает MockTwitterClient, который дает некоторый результат теста.

Теперь позвольте мне прийти к моей точке. Я использую MEF для внедрения зависимости (но я довольно плохо знаком с этим). Что я делаю, это:

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

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

Принимая во внимание, что мой DefaultTwitterClientFactory экспортируется в MEF:

[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?)

1 Ответ

3 голосов
/ 03 мая 2011

Вам не нужно использовать композитор / контейнер в ваших модульных тестах - просто подключите SUT напрямую к Test Doubles .

Примерно так:

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

Тем не менее, вам действительно нужно выполнить рефакторинг от Инъекции свойства до Инъекции конструктора, поскольку свойство подразумевает, что зависимость является необязательной.не экспортирует сам, он экспортирует ITwitterClient.

...