2012-05-05 3 views
10

Say У меня есть следующие:Как издеваются вызов метода, который принимает динамический объект

public interface ISession 
{ 
    T Get<T>(dynamic filter); } 
} 

И я следующий код, который я хочу, чтобы тест:

var user1 = session.Get<User>(new {Name = "test 1"}); 
var user2 = session.Get<User>(new {Name = "test 2"}); 

Как бы я издеваться этот звонок?

Используя Moq, я устал делать это:

var sessionMock = new Mock<ISession>(); 
sessionMock.Setup(x => x.Get<User>(new {Name = "test 1")).Returns(new User{Id = 1}); 
sessionMock.Setup(x => x.Get<User>(new {Name = "test 1")).Returns(new User{Id = 2}); 

И это не сработало. Возвращенные результаты равна нулю

Я также попытался сделать следующее с Rhino иронизирует:

var session = MockRepository.GenerateStub<ISession>(); 
session.Stub(x => x.Get<User>(new {Name = "test 1"})).Return(new User{Id=1}); 

не повезло либо. Нуль снова.

Итак, как бы я это сделал?

Спасибо,

ответ

22

О решении заключается в использовании It.Is<object> Искателя вместе с отражением. Вы не можете использовать динамический в деревья выражений так It.Is<dynamic> не будет работать, поэтому вам нужно отражение, чтобы получить ваше значение свойства по имени:

sessionMock 
    .Setup(x => x.Get<User>(
     It.Is<object>(d => d.GetPropertyValue<string>("Name") == "test 1"))) 
    .Returns(new User{Id = 1}); 
sessionMock 
    .Setup(x => x.Get<User>(
     It.Is<object>(d => d.GetPropertyValue<string>("Name") == "test 2"))) 
    .Returns(new User { Id = 2 }); 

Где GetPropertyValue это маленький помощник:

public static class ReflectionExtensions 
{ 
    public static T GetPropertyValue<T>(this object obj, string propertyName) 
    { 
     return (T) obj.GetType().GetProperty(propertyName).GetValue(obj, null); 
    } 
} 
+0

Perfect! Именно то, что мне нужно. Спасибо! –

0

Moq при условии It.IsAny<T> для этого случая

sessionMock.Setup(x => x.Get<User>(It.IsAny<object>()).Returns(new User()); 

* динамика любого объекта

+1

Спасибо ai.farfa. Я не могу этого сделать, потому что мне нужно указать, какой объект будет возвращаться на основе различных свойств динамического объекта. –

1

Прежде все, анонимные объекты на самом деле не dynamic.

Если вы использовали dynamic объекты, такие как

dynamic user1Filter = new ExpandoObject(); 
user1Filter.Name = "test 1"; 
var user1 = session.Get<User>(user1Filter); 

вы могли дразнить его, как

sessionMock.Setup(x => x.Get<User>(DynamicFilter.HasName("test 1"))); 

путем реализации пользовательских аргументов Искателя:

static class DynamicFilter 
{ 
    [Matcher] public static object HasName(string name) { return null; } 
    public static bool HasName(dynamic filter, string name) 
    { 
     string passedName = filter.Name; //dynamic expression 
     return name.Equals(passedName); 
    } 
} 
Смежные вопросы