MEF и модуль тестирования с NUNIT
-
27-09-2019 - |
Вопрос
Несколько недель назад я прыгнул на MEF (ComponentModel) Bandwag, и теперь использую его для многих моих плагинов, а также общих библиотек. В целом, это было здорово в стороне от частых ошибок с моей стороны, что приведет к расстраиванию сеансов отладки.
Во всяком случае, мое приложение работает отлично, но мои изменения, связанные с 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, используя это для всех испытаний.
Хорошо, вот мои вопросы относительно этой ситуации:
- Это плохой способ делать вещи?
- Вы бы порекомендовали сочинять запчасти в [Настройка
- Я еще не узнал, как использовать издевательства в тестировании подразделения - это хороший пример случая, когда я мог бы захотеть издеваться в базовую базу данных (как-то), чтобы просто вернуть фиктивные данные, а не на самом деле не требуют базы данных?
- Если вы столкнулись с чем-то вроде этого ранее, вы можете предложить свой опыт и то, как вы решили свою проблему? (или должен зайти в сообщество Wiki?)
Решение
Похоже, вы находитесь на правильном пути. Тест подразделения должен проверить Ед. изм, И вот что вы делаете, когда вы напрямую создаете экземпляры. Если вы позволите MEF составить для вас экземпляры, они будут склонны к Тесты интеграции. Отказ Не то, что есть что-то не так с тестами интеграции, но тесты единиц, как правило, более поддерживаются, потому что вы тестируете каждый агрегат в изоляции.
Вам не нужен контейнер для проводных экземпляров в модульных тестах.
Я вообще рекомендую против сочинения приспособлений при настройке, так как это приводит к Общее крепление антизаблоки.
Лучше всего заменить зависимости с Тест удваивается. Отказ Динамические издевательства являются одним из более универсальных способов этого, настолько то, что вы должны учиться.
Другие советы
Я согласен, что создание документов вручную намного лучше, чем использование контейнера для композиции MEF, чтобы удовлетворить импорт, но относительно примечание.
Если вы используете статический контейнер и удовлетворите импорт через композициюInitializer.satisFyimports, вам придется столкнуться с общим моментом прибора, что и композициониализатор. Инициализация не может быть вызвана более одного раза. Тем не менее, вы всегда можете создавать композицию Container, добавить каталоги и вызовите удовлетворить на сам контейнер. В этом случае вы можете использовать новый состав Container в каждом тесте и уйти с обращенным с общим / общим прибором
Я заблокировал, как делать модульные тесты (не NUNIT, но работает только то же самое) с MEF. Хитрость состояла в том, чтобы использовать MOCKEXPORTPROVIDER, и я создал тестовую базу для всех моих тестов, чтобы наследовать.
Это моя главная функция автосистемы, которая работает для тестов интеграции и единиц:
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/