2010-02-05 3 views
5

Я пытаюсь проверить свойство, которое вложен в дочерний класс. Я всегда получаю сообщение об ошибке. Я что-то упустил? Возможно ли проверить свойство ребенка в moq.Mocking ChildProperty не может заставить его работать?

У меня есть следующие

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

ответ

3

Вы не можете дразнить OrderDataCollection свойство CustomerInfo, потому что это не виртуальные собственности на конкретный класс.

Самый лучший способ, чтобы исправить это было бы извлечь из интерфейса CustomerInfo и пусть IOrderView возвращение, что вместо того, чтобы:

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

Спасибо за ваш ответ. Вы говорите, что я должен сделать это свойство виртуальным, и оно будет работать? – user9969

+1

Создание виртуального приложения OrderDataCollection также может работать. С другой стороны, свойства коллекции должны быть доступны только для чтения. –

+0

Спасибо большое Я, кажется, понимаю это сейчас. Я сделал интерфейс – user9969

1

Это, безусловно, возможно, если у вас есть право абстракций. Вы должны издеваться свой Customer и его дети тоже, ваш пример работать, как:

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

и т.д. для всей иерархии дочерних объектов вы хотите контролировать с издевается. Надеюсь, это имеет смысл.

/Klaus

+0

Спасибо за ваш ответ. По-прежнему не удается получить сбор. Работает Я хотел бы проверить mock.Customer.OrderCollection.Count = 2 это возможно? – user9969

+0

orderViewMock.SetupGet (o => o.Customer.OrderCollection). Возвраты (orderViewMock.Object.Customer.OrderCollection); Выше было то, что я пробовал – user9969

+0

Нет, как указано выше, Маркс Seemann, вы можете только издеваться над абстрактными классами и интерфейсами, поэтому вам нужно абстрагироваться от 'OrderCollection', а для этого работать. –

0

вы получите ошибку во время выполнения, как вы нашли:

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

Вы можете высмеять IOrderView и вернуть любой экземпляр CustomerInfo, который вы хотите, но вы также пытаетесь высмеять CustomerInfo и OrderCollection. Как отметил Марк Семанн, вы можете только обманывать интерфейсы и виртуальные свойства/методы. Это будет справедливо для практически любой издевательств/изоляции, за исключением Typemock (коммерческий).

Как уже было сказано, одним из способов решения проблемы является возврат интерфейса для клиента.

Смежные вопросы