2010-02-05 2 views
5

하위 클래스에 중첩 된 속성을 테스트하려고합니다. 나는 항상 오류가 발생합니다. 내가 빠진 것이 있습니까? moq에서 하위 속성을 테스트 할 수 있습니까?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

당신은 CustomerInfo의 OrderDataCollection 속성을 조롱 수 없습니다.

CustomerInfo에서 인터페이스를 추출하고 그 대신 IOrderView 반환하도록하는 것이 문제를 해결하는 가장 좋은 방법 : 당신이 발견 한대로,

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

답장을 보내 주셔서 감사합니다. 그 속성을 가상으로 만들어야한다고 말하는가? – user9969

+1

OrderDataCollection 가상을 만드는 것도 효과가있을 수 있습니다. 또 다른 메모에서 컬렉션 속성은 읽기 전용이어야합니다. –

+0

고마워요 지금 이해하고있는 것 같습니다. 인터페이스를 만들었습니다. – user9969

1

를 다음 그것은 확실히 수 있습니다. 아이의 전체 계층 구조에 대한

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

등의 객체를

당신이 모의 객체로 제어 할 : 당신은 당신의 예제가 작동하려면처럼, 너무 당신의 Customer와 아이를 조롱 할 필요가있다. 그것이 의미가 있기를 바랍니다. 그것은 구체적인 클래스의 가상이 아닌 속성이 있기 때문에

/클라우스

+0

답장을 보내 주셔서 감사합니다. 여전히 컬렉션을 가져올 수 없습니다. 카운트 작업 mock.Customer.OrderCollection.Count = 2 을 확인하고 싶습니다. – user9969

+0

orderViewMock.SetupGet (o => o.Customer.OrderCollection). 반환 (orderViewMock.Object.Customer.OrderCollection); 위의 내용은 내가 시도한 것입니다. – user9969

+0

아니요. @Mark 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도 조롱하려고합니다. Mark Seemann이 언급했듯이 인터페이스와 가상 속성/메소드 만 조롱 할 수 있습니다. 이는 Typemock (상업용)을 제외한 거의 모든 조롱/격리 프레임 워크에서 유효합니다.

다른 사람들이 이미 언급했듯이 문제를 해결하는 한 가지 방법은 고객을위한 인터페이스를 반환하는 것입니다.

관련 문제