2010-02-05 17 views
5

Tôi đang cố kiểm tra thuộc tính được lồng trong lớp con. Tôi luôn gặp lỗi. Tôi có thiếu gì đó không? Có thể kiểm tra thuộc tính con trong moq không.Mocking ChildProperty không thể làm cho nó hoạt động?

Tôi có sau

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

Trả lời

3

Bạn không thể giả lập thuộc tính OrderDataCollection của CustomerInfo vì đó là thuộc tính không ảo trên lớp bê tông.

Cách tốt nhất để khắc phục điều này sẽ được trích xuất một giao diện từ customerinfo và để IOrderView trở lại mà thay vào đó:

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

Cảm ơn bạn đã trả lời. Bạn có nói rằng tôi nên biến thuộc tính đó thành ảo và nó sẽ hoạt động không? – user9969

+1

Làm cho OrderDataCollection ảo cũng có thể hoạt động. Trên ghi chú khác, thuộc tính bộ sưu tập phải là chỉ đọc. –

+0

Cảm ơn rất nhiều Tôi có vẻ đã hiểu nó ngay bây giờ. Tôi đã tạo một Giao diện – user9969

1

Nó chắc chắn là có thể nếu bạn có trừu tượng đúng. Bạn cần phải thử Customer của bạn và con của nó cũng vậy, ví dụ bạn để làm việc, như:

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

vv cho toàn bộ hệ thống các đối tượng trẻ em bạn muốn kiểm soát với mocks. Hy vọng nó có ý nghĩa.

/Klaus

+0

Cảm ơn bạn đã trả lời. Vẫn không thể nhận được bộ sưu tập. Làm việc toàn thời gian Tôi muốn xác minh mock.Customer.OrderCollection.Count = 2 là điều này có thể? – user9969

+0

orderViewMock.SetupGet (o => o.Customer.OrderCollection) .Returns (orderViewMock.Object.Customer.OrderCollection); Ở trên là những gì tôi đã thử – user9969

+0

Không, như @Mark Seemann đã nói ở trên, bạn chỉ có thể giả lập các lớp trừu tượng và các giao diện, vì vậy bạn cần trừu tượng 'OrderCollection' để làm việc đó. –

0

Bạn sẽ nhận được một lỗi thời gian chạy, như bạn đã thấy:

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

Bạn có thể giả lập IOrderView và trả về bất kỳ cá thể CustomerInfo nào bạn muốn, nhưng bạn cũng đang cố gắng giả lập CustomerInfo và OrderCollection. Như Mark Seemann đã đề cập, bạn chỉ có thể giả lập giao diện và các thuộc tính/phương thức ảo. Điều này sẽ đúng đối với hầu hết mọi khuôn khổ mô phỏng/cách ly trừ Typemock (thương mại).

Như những người khác đã nêu, một cách để giải quyết vấn đề là trả lại giao diện cho khách hàng.

Các vấn đề liên quan