2012-05-05 16 views
10

Decir que tengo el siguiente:Cómo se burlan de una llamada a un método que toma un objeto dinámico

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

y tengo el siguiente código que desee probar:

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

¿cómo iba a burlarse ¿esta llamada?

Usando Moq, que cansado de hacer esto:

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

Y eso no funcionó. Los resultados devueltos es nula

También traté de hacer lo siguiente con burla de Rhino:

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

No hubo suerte tampoco. Nulo de nuevo.

Entonces, ¿cómo podría hacer esto?

Gracias,

Respuesta

22

En solución es utilizar el matcher It.Is<object> junto con la reflexión. No se puede utilizar dinámica en los árboles de expresión de modo It.Is<dynamic> no va a funcionar es por eso que necesita la reflexión para obtener el valor de su propiedad por su nombre:

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

Dónde GetPropertyValue es un pequeño ayudante:

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

¡Perfecto! Exactamente lo que necesito ¡Gracias! –

0

Moq proporcionado It.IsAny<T> para ese caso

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

* dinámico es cualquier objeto

+1

Gracias ai.farfa. No puedo hacer eso porque necesito decir qué objeto devolver según las diferentes propiedades en el objeto dinámico –

1

primer todos, los objetos anónimos no son realmente dynamic.

Si utilizó dynamic objetos como

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

se podía burlarse de ella como

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

mediante la implementación personalizada argumento de coincidencias:

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