2010-02-05 5 views
5

Ich versuche, eine Eigenschaft zu testen, die in einer untergeordneten Klasse verschachtelt ist. Ich bekomme immer einen Fehler. Fehle ich etwas? Ist es möglich, eine untergeordnete Eigenschaft in moq zu testen?Mocking ChildProperty kann es nicht zum Funktionieren bringen?

Ich habe folgendes

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

Antwort

3

Sie können nicht die OrderDataCollection Eigenschaft Customer verspotten, weil es auf eine konkrete Klasse ein nicht-virtuelles Eigentum ist.

Der beste Weg, dies zu beheben wäre eine Schnittstelle von Customer zu extrahieren und IOrderView zurück, die stattdessen lassen:

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

Vielen Dank für Ihre Antwort. Willst du damit sagen, dass ich diese Eigenschaft virtuell machen soll und es funktioniert? – user9969

+1

Die virtuelle OrderDataCollection könnte ebenfalls funktionieren. In einem anderen Hinweis sollten Auflistungseigenschaften schreibgeschützt sein. –

+0

Vielen Dank Ich scheint es jetzt zu verstehen. Ich habe eine Schnittstelle gemacht – user9969

1

es auf jeden Fall möglich ist, wenn man die richtigen Abstraktionen haben. Sie benötigen Customer und seine Kinder zu verspotten, für Ihr Beispiel funktioniert, wie:

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

usw. für die gesamte Hierarchie der untergeordneten Objekte möchten Sie mit Mocks steuern. Ich hoffe es macht Sinn.

/Klaus

+0

Vielen Dank für Ihre Antwort. Noch kann die Sammlung nicht erhalten. Count funktioniert Ich möchte überprüfen, die mock.Customer.OrderCollection.Count = 2 ist dies möglich? – user9969

+0

orderViewMock.SetupGet (o => o.Customer.OrderCollection) .Returns (orderViewMock.Object.Customer.OrderCollection); Das obige ist, was ich ausprobiert – user9969

+0

Nein, wie @Mark Seemann oben gesagt, können Sie abstrakte Klassen und Schnittstellen nur mock, also müssen Sie die 'OrderCollection' abstrahieren, damit auch das funktioniert. –

0

Sie erhalten einen Laufzeitfehler erhalten, wie Sie gefunden haben:

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

Sie können die IOrderView nachahmen und eine beliebige CustomerInfo-Instanz zurückgeben, aber Sie versuchen auch, CustomerInfo und OrderCollection nachzuahmen. Wie Mark Seemann erwähnt hat, können Sie nur Schnittstellen und virtuelle Eigenschaften/Methoden vortäuschen. Dies gilt für fast jedes Spott/Isolations-Framework mit Ausnahme von Typemock (kommerziell).

Wie andere schon gesagt haben, ist eine Möglichkeit, das Problem zu lösen, eine Schnittstelle für den Kunden zurückzugeben.

Verwandte Themen