2011-03-09 7 views
12

Estoy tratando de probar con Moq que se llama a un método que tiene una lista de "params", pero por alguna razón esto está fallando. La firma del método es algo como esto:Moq - Verifique la llamada al método que tiene un valor de parámetro

void AttachAsModifiedToOrders(IOrder order, params 
     Expression<Func<IOrder, object>>[] modifiedProperties); 

Luego, en la configuración Mock que he hecho algo como esto para hacer un simple "eliminar/insertar" de la colección burlado:

MockEntities.Setup(n => n.AttachAsModifiedToOrders(It.IsAny<DataAccess.Order>())) 
    .Callback<IOrder, Expression<Func<IOrder, object>>[]>((order, expr) => 
     { Orders.Remove(Orders.Where(o => o.Id== order.Id).First()); 
     Orders.Add((DataAccess.Order)order); }); 

Por último, la verificación:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), 
    It.IsAny<Expression<Func<IOrder, object>>>()), Times.Exactly(1)); 

he comprobado, y el código se ejecuta bien y se llama al método (el burlaban de uno), pero la verificación está fallando. ¿Me estoy perdiendo de algo? ¿O simplemente es que Moq no admite esta llamada "params"?

+0

¿Qué versión de Moq? –

+0

el conjunto dice 4.0.0 –

+0

Ah, vale. Vi una publicación de error anterior acerca de 3 y 3.1. –

Respuesta

12

Tuve dificultades para reproducir esto. Creo que hay un error tipográfico en su verificar:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), It.IsAny<Expression<Func<IOrder, object>>>()), Times.Exactly(1)); 

debe ser:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), It.IsAny<Expression<Func<IOrder, object[]>>>()), Times.Exactly(1)); 

que también se preguntan si la primera It.IsAny debe ser la interfaz y no el tipo concreto?

Sin embargo, esta es una prueba demasiado complicada de algunas funcionalidades, y al ejemplo de código le faltan algunas piezas, como el tipo de DataAccess o instancia de clase (¿no está seguro?), Pedido y Órdenes.

Para evitar eso, crearon la interfaz iOrder y un objeto manipulador que utiliza la interfaz, es un poco sin sentido, sino que impulsa la prueba:

public interface IOrder 
{ 
    void AttachAsModifiedToOrders(IOrder order, params Expression<Func<IOrder, object[]>>[] modifiedProperties); 

} 

public class Manipulator 
{ 
    public Manipulator(IOrder order) 
    { 
     Expression<Func<IOrder, object[]>> exp = o => new object[0]; 
     order.AttachAsModifiedToOrders(order, exp); 
    } 

    public void DoStuff() { } 
} 

Entonces creé un accesorio de prueba para validar la params arg:

[TestFixture] 
public class Tester 
{ 
    [Test] 
    public void Test() 
    { 
     var order = new Mock<IOrder>(); 
     order.Setup(n => n.AttachAsModifiedToOrders(It.IsAny<IOrder>())); 

     var manipulator = new Manipulator(order.Object); 
     manipulator.DoStuff(); 

     order.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<IOrder>(), It.IsAny<Expression<Func<IOrder, object[]>>>()), Times.Once()); 
    } 
} 

Esto funciona para mí, así que no creo que el problema es el valor params y Moq directamente. Creo que estarás bien para dar un paso atrás y ver si realmente estás probando las unidades de la clase que interactúa con el simulacro, o tratando de verificar usos integrados de un par de tipos diferentes. Los params y el árbol de expresiones también son un poco olorosos.

+0

acaba de darse cuenta de que la verificación no se llamaba con el parámetro param, pero muchas gracias por tomarse el tiempo para hacer esta prueba. es un poco engorroso tener que especificar todo esto, pero bueno ... –

+1

Creo que si es difícil de probar, entonces es probablemente difícil de expresar y difícil de entender. Vale la pena considerar una mirada. –

Cuestiones relacionadas