Динамический вызов Moq Setup () во время выполнения

Я хочу создать фабрику, которая будет создавать обычно имитируемые объекты для моих модульных тестов. Мне уже удалось настроить свои тесты, чтобы я мог смоделировать Linq2Sql DataContext и вернуть таблицу в памяти вместо обращения к базе данных. Я установил его так:

_contactsTable = new InMemoryTable<Contact>(new List<Contact>());
_contactEmailsTable = new InMemoryTable<ContactEmail>(new List<ContactEmail>());
//  repeat this for each table in the ContactsDataContext

var mockContext = new Mock<ContactsDataContext>();
mockContext.Setup(c => c.Contacts).Returns(_contactsTable);
mockContext.Setup(c => c.ContactEmails).Returns(_contactEmailsTable);
// repeat this for each table in the ContactsDataContext

Это становится утомительным, если DataContext содержит много таблиц, поэтому я подумал, что может помочь простой фабричный метод, который использует отражение для извлечения всех таблиц из DataContext:

public static DataContext GetMockContext(Type contextType)
{
    var instance = new Mock<DataContext>();
    var propertyInfos = contextType.GetProperties();
    foreach (var table in propertyInfos)
    {
        //I'm only worried about ITable<> now, otherwise skip it
        if ((!table.PropertyType.IsGenericType) ||
            table.PropertyType.GetGenericTypeDefinition() != typeof (ITable<>)) continue;

        //Determine the generic type of the ITable<>
        var TableType = GetTableType(table);
        //Create a List<T> of that type 
        var emptyList = CreateGeneric(typeof (List<>), TableType);
        //Create my InMemoryTable<T> of that type
        var inMemoryTable = CreateGeneric(typeof (InMemoryTable<>), TableType, emptyList);  

        //NOW SETUP MOCK TO RETURN THAT TABLE
        //How do I call instance.Setup(i=>i.THEPROPERTYNAME).Returns(inMemoryTable) ??
    }
return instance.Object;
}

Пока что я ' Мы выяснили, как создавать объекты, которые мне нужно настроить для Mock, но я просто не могу понять, как динамически вызывать Moq Setup (), передавая имена свойств. Я начал искать отражение в методе Invoke () Moq Setup (), но он стал ужасно быстрым.

Есть ли у кого-нибудь простой способ динамически вызывать Setup () и Returns (), как это?

Edit ]: Ответ Брайана привел меня туда. Вот как это работает:

public static DataContext GetMockContext<T>() where T: DataContext
    {
        Type contextType = typeof (T);
        var instance = new Mock<T>();
        var propertyInfos = contextType.GetProperties();
        foreach (var table in propertyInfos)
        {
            //I'm only worried about ITable<> now, otherwise skip it
            if ((!table.PropertyType.IsGenericType) ||
                table.PropertyType.GetGenericTypeDefinition() != typeof(ITable<>)) continue;

            //Determine the generic type of the ITable<>
            var TableType = GetTableType(table);
            //Create a List<T> of that type 
            var emptyList = CreateGeneric(typeof(List<>), TableType);
            //Create my InMemoryTable<T> of that type
            var inMemoryTable = CreateGeneric(typeof(InMemoryTable<>), TableType, emptyList);

            //NOW SETUP MOCK TO RETURN THAT TABLE
            var parameter = Expression.Parameter(contextType);
            var body = Expression.PropertyOrField(parameter, table.Name);
            var lambdaExpression = Expression.Lambda<Func<T, object>>(body, parameter); 

            instance.Setup(lambdaExpression).Returns(inMemoryTable);
        }
        return instance.Object;
    }
6
задан Jake Stevenson 1 August 2011 в 15:45
поделиться