2012-05-05 10 views
10

że mam następujące:Jak mock wywołanie metody, która pobiera obiekt dynamiczny

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

i mam następujący kod, który chcę testu:

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

Jak bym drwić to połączenie?

Korzystanie Min, ja zmęczony tym idzie:

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}); 

I to nie działa. Wyniki zwracane jest null

Próbowałem również wykonać następujące czynności z Rhino Mocks:

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

No szczęście albo. Null ponownie.

Jak to zrobić?

Dzięki,

Odpowiedz

22

Na rozwiązaniem jest użycie It.Is<object> dopasowywania wraz z refleksji. Nie można korzystać z dynamicznego na drzewach ekspresyjnych tak It.Is<dynamic> nie zadziała dlatego trzeba odbicie, aby uzyskać swoją wartość nieruchomości według nazwy:

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 }); 

Gdzie GetPropertyValue jest trochę pomocnik:

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

Doskonały! Dokładnie to, czego potrzebuję. Dziękuję Ci! –

0

Moq warunkiem It.IsAny<T> dla tego przypadku

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

* dynamiczny jest dowolny obiekt

+1

Thanks ai.farfa. Nie mogę tego zrobić, ponieważ muszę powiedzieć, który obiekt powrócić na podstawie różnych właściwości dynamicznego obiektu. –

1

pierwsze wszystkie anonimowe obiekty nie są tak naprawdę dynamic.

Jeśli użyto dynamic obiektów jak

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

można drwić go jak

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

wdrażając matcher niestandardowych argumentów:

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); 
    } 
} 
Powiązane problemy