2010-02-05 14 views
5

Sto provando a testare una proprietà che è annidata in una classe figlia. Ho sempre un errore. Mi manca qualcosa? E 'possibile testare una proprietà figlio in moq.Mocking ChildProperty non riesce a farlo funzionare?

Ho il seguente

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

risposta

3

Non si può prendere in giro la proprietà OrderDataCollection di CustomerInfo perché è una struttura non-virtuale su una classe concreta.

Il modo migliore per risolvere questo problema sarebbe quello di estrarre un'interfaccia da CustomerInfo e lasciare ritorno IOrderView che invece:

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

Grazie per la risposta. Stai dicendo che dovrei rendere virtuale quella proprietà e funzionerà? – user9969

+1

Anche la creazione di OrderDataCollection virtuale potrebbe funzionare. In un'altra nota, le proprietà della raccolta devono essere di sola lettura. –

+0

Grazie mille Mi sembra di capire ora. Ho realizzato un'interfaccia – user9969

1

è sicuramente possibile se si hanno le astrazioni di destra. È necessario prendere in giro la vostra Customer e dei suoi figli anche, per il vostro esempio funzioni, come:

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

ecc per l'intera gerarchia del bambino oggetti che si desidera controllare con schernisce. Spero che abbia senso.

/Klaus

+0

Grazie per la risposta. Ancora non riesco a ottenere la collezione. Lavoro attivo Vorrei verificare il mock.Customer.OrderCollection.Count = 2 è possibile? – user9969

+0

orderViewMock.SetupGet (o => o.Customer.OrderCollection) .Returns (orderViewMock.Object.Customer.OrderCollection); Quanto sopra è quello che ho provato – user9969

+0

No, come @Mark Seemann ha affermato in precedenza, è possibile solo prendere in giro classi e interfacce astratte, quindi è necessario astrarre "OrderCollection" e farlo funzionare. –

0

otterrete un errore di runtime, come hai trovato:

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

È possibile prendere in giro IOrderView e restituire qualsiasi istanza CustomerInfo che si desidera, ma si sta anche cercando di prendere in giro CustomerInfo e OrderCollection. Come ha detto Mark Seemann, puoi solo prendere in giro interfacce e proprietà/metodi virtuali. Ciò è valido per quasi tutti i framework di derisione/isolamento ad eccezione di Typemock (commerciale).

Come altri hanno già affermato, un modo per risolvere il problema è restituire un'interfaccia per il cliente.

Problemi correlati