2015-09-11 8 views
0

Что я пытаюсь сделать, это обобщить создание репозиториев с помощью AutoFixture и Moq. У меня есть метод под названием 'add', который добавляет поддельные записи в список. Список называется записями и является глобальным для класса. Генерирование M является моделью, которую нужно издеваться. Метод возвращает «this», поэтому метод может быть привязан.Передача свойства универсального класса в качестве параметра в AutoMoq

public Repo<M> add(string prop, string val) { 
    var a = fixture.Build<M>().With(m => m.GetProperty(prop), val).Create(); 
    records.Add(a); 
    return this; 
} 

с классом расширения (я нашел этот поиск SO):

public static class MyExtensions 
{ 
    public static object GetProperty<T>(this T obj, string name) where T : class 
    { 
     Type t = typeof(T); 
     return t.GetProperty(name).GetValue(obj, null); 
    } 
} 

Ошибка я получаю "ArgumentException произошло в Ploeh.AutoFixture.dll".

Вопрос: Как передать свойство общего объекта в качестве параметра метода, когда модель неизвестна во время компиляции?

+1

В качестве побочного элемента ваш метод 'add' должен быть назван' Add' вместо этого, в соответствии с [правилами именования] (https://msdn.microsoft.com/en-us/library/vstudio/ms229043 (v = VS.100) .aspx). – dcastro

ответ

4

With метод требует Expression<Func<T, TProperty>> параметр не PropertyInfo.

Вы можете изменить свой метод add взять Expression<Func<T, TProperty>> вместо строки:

public Repo<M> add<T>(Expression<Func<M, T>> propertyPicker, T val) 
{ 
    var a = fixture.Build<M>().With(propertyPicker, val).Create(); 
    records.Add(a); 
    return this; 
} 

и это использование:

add(foo => foo.Name, "abc"); 
+0

Спасибо! Прекрасно работает. –

0

Большое спасибо ARKADIUSZ за правильный ответ. Я просто хочу, чтобы добавить этот метод, который я добавил (вдохновленный несколько SO сообщений), чтобы создать выражение, так что использование было бы: add("username","me")

private Expression<Func<M,T>> makeExpression<T>(string prop, T val) 
{ 
    var m = Expression.Parameter(typeof(M), "m"); 
    Expression columnExpr = Expression.Property(m,typeof(M).GetProperty(prop)); 

    return Expression.Lambda<Func<M, T>>(columnExpr, m); 
} 

Затем в методе добавления, я изменил propertyPicker к makeExpression(property,val), property являющееся именем свойства в виде строки.

+0

'makeExpression' должно быть' MakeExpression'. [Руководство по именованию] (https://msdn.microsoft.com/en-us/library/vstudio/ms229043 (v = vs.100) .aspx) –

+0

Вы должны знать, что вы подали заявку на компиляцию, проверяет, существует ли свойство в классе 'M'. Это означает, что если вы, например, измените имя свойства с помощью инструмента рефакторинга, этот инструмент не изменит литерал имени свойства, если он не поддерживает поиск в строковых литералах. –

 Смежные вопросы

  • Нет связанных вопросов^_^