2010-02-05 32 views
5

Estoy tratando de probar una propiedad que está anidada en una clase secundaria. Siempre me sale un error. ¿Me estoy perdiendo algo? ¿Es posible probar una propiedad infantil en moq.¿Mocking ChildProperty no puede hacer que funcione?

Tengo el siguiente

 [Test] 
public void Should_be_able_to_test_orderCollection() 
    { 
     var orderViewMock = new Mock<IOrderView>(); 
     orderViewMock.SetupGet(o => o.Customer.OrderDataCollection.Count).Returns(2);   

     orderViewMock.SetupSet(o => o.Customer.OrderDataCollection[1].OrderId = 1); 

     orderViewMock.VerifySet(o => o.Customer.OrderDataCollection[1].OrderId=1); 
    } 

    public class CustomerTestHelper 
    { 
     public static CustomerInfo GetCustomer() 
     { 
      return new CustomerInfo 
      { 
       OrderDataCollection = new OrderCollection 
       { 
        new Order {OrderId = 1}, 
        new Order {OrderId = 2} 
       } 
      }; 

     } 
    } 
    public class CustomerInfo 
    { 
     public OrderCollection OrderDataCollection { get; set; } 
    } 

    public class OrderCollection:List<Order> 
    { 
    } 

    public class Order 
    { 
     public int OrderId { get; set; } 
    } 
    public interface IOrderView 
    { 
     CustomerInfo Customer { get; set; } 
    } 

Respuesta

3

Usted no puede burlarse de la propiedad OrderDataCollection de CustomerInfo porque es una propiedad para no virtual en una clase concreta.

La mejor manera de solucionar este problema sería la de extraer una interfaz de CustomerInfo y dejar retorno IOrderView que en lugar:

public interface IOrderView 
{ 
    ICustomerInfo Customer { get; set; } 
} 
+0

Gracias por su respuesta. ¿Estás diciendo que debería hacer que esa propiedad sea virtual y funcionará? – user9969

+1

Hacer que OrderDataCollection virtual también funcione. En otra nota, las propiedades de la colección deben ser de solo lectura. –

+0

Muchas gracias Parece que lo entiendo ahora. Hice una interfaz – user9969

1

es definitivamente posible si tiene las abstracciones adecuadas. Es necesario para burlarse de su Customer y sus hijos también, por su ejemplo de trabajo, como:

var customerMock = new Mock<ICustomer>(); 
orderViewMock.SetupGet(o => o.Customer).Returns(customerMock.Object); 

etc. para toda la jerarquía de objetos secundarios que desea controlar con burla. Espero que tenga sentido.

/Klaus

+0

Gracias por su respuesta. Todavía no se puede obtener la colección.Count working Me gustaría verificar que el mock.Customer.OrderCollection.Count = 2 ¿es esto posible? – user9969

+0

orderViewMock.SetupGet (o => o.Customer.OrderCollection) .Returns (orderViewMock.Object.Customer.OrderCollection); Lo anterior es lo que probé – user9969

+0

No, como se mencionó anteriormente en @Mark Seemann, solo puede simular clases e interfaces abstractas, por lo que debe abstraer el 'OrderCollection' también para que funcione. –

0

obtendrá un error de ejecución, como has encontrado:

System.ArgumentException: Invalid setup on a non-overridable member: 
o => o.Customer.OrderDataCollection.Count 
at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo methodInfo) 

Puede simular IOrderView y devolver cualquier instancia de CustomerInfo que desee, pero también está intentando burlarse de CustomerInfo y OrderCollection. Como mencionó Mark Seemann, solo puedes simular interfaces y propiedades/métodos virtuales. Esto será válido para casi cualquier marco de burla/aislamiento, excepto para Typemock (comercial).

Como ya se ha mencionado, una forma de resolver el problema es devolver una interfaz para el cliente.

Cuestiones relacionadas