2009-06-10 16 views
3

우리는 많은 ASP.Net 서버 컨트롤을 개발했으며이를 테스트해야합니다. 컨트롤을 인스턴스화하고, 일부 속성을 설정하고, CreateChildControls를 호출하고 컨트롤 계층 구조를 테스트하려고합니다.asp.net 서버 컨트롤을 테스트하는 방법

내가 문제의 번호로 실행

  1. 컨트롤이 HttpContext를
  2. 을 CreateChildControls에 의존하는) (

심지어 Controls 컬렉션에 하나의 자식 컨트롤을 ResolveAdapter 호출을 추가하는 개인이다 메서드는 HttpContext에 의존합니다.

어떻게이 문제를 해결할 수 있습니까?

p.s. 페이지 (!)에서 컨트롤을 테스트하고 싶지 않습니다.

+0

사용자 정의 컨트롤을 만드시겠습니까? –

답변

1

컨트롤의 실제 렌더링은 신경 쓰지 않지만 컨트롤에는 로직이 포함되어 있습니다. 이를 위해 HttpContext 외부에서 컨트롤을 테스트 할 수 없다는 것 외에도 다른 문제가 있음을 제안합니다.

로직이 컨트롤에만 관련된 경우에는 프레임 워크가 작업을 수행하도록 신뢰해야하며 페이지에 컨트롤을 놓아 제대로 작동하는지 확인해야합니다. 테스트하려는 논리가 비즈니스 논리이면 리팩터링해야합니다.

비즈니스 로직을 별도의 Project/Dll 어딘가에 가져오고 서버 컨트롤에 MVP pattern을 구현하는 것에 대해 생각해보십시오. WCSF와 같이 큰 무거운 프레임 워크를 사용하지 않아도됩니다. 개념적으로 약간의 노력으로이를 구현할 수 있습니다.

보기에 값을 나타내는 인터페이스 만들기 :

public class OrderPresenter 
{ 
    public IOrderView View {get; set;} 

    public void InitializeView() 
    { 
     //Stuff that only happens when the page loads the first time 

     //This is only for an example: 
     var order = Orders.GetOrder(custId); 

     View.ID = order.ID; 
     View.Name = order.Name; 
     View.Items = order.Items; 
    } 

    public void LoadView() 
    { 
     //Stuff that happens every page load 
    } 
} 

이제 서버 컨트롤이 구현할 수 :이 정의되면, 당신이보기를 행사 발표자 필요

public interface IOrderView 
{ 
    Int32 ID{get; set;} 
    String Name{get; set;} 
    List<Item> Items {set;} 
} 

을 인터페이스를 사용하여 초기화하고 OrderPresenter

public class OrderControl: Panel, IOrderView 
{ 
    private OrderPresenter Presenter{get; set;} 

    public OrderControl() 
    { 
     //Create new presenter and initialize View with reference 
     // to ourselves 
     Presenter = new OrderPresenter{View = this;} 
    } 

    protected override void OnLoad(EventArgs e) 
    { 
     if(Page.IsPostback) 
     { 
      _presenter.InitializeView(); 
     } 

     _presenter.LoadView(); 

     //Other normal onload stuff here... 
    } 

    //Now for the interface stuff 
    public Int32 ID 
    { 
     get{ return Int32.Parse(lblOrderId.Text); } 
     set{ lblOrderId.Text = value.ToString(); } 
    } 

    public String Name 
    { 
     get{ return lblOrderName.Text; } 
     set{ lblOrderName.Text = value; } 
    } 

    public List<Item> Items 
    { 
     set 
     { 
      gvItems.DataSource = value; 
      gvItems.DataBind(); 
     } 
    } 
} 

그리고 당신은 그것을 가지고 있습니다! 스텁 아웃 된 뷰를 사용하여 OrderPresenter에 대한 단위 테스트를 작성할 수 있어야합니다. HttpContext는 필요하지 않으며, 당신은 더 명확한 관심사를 가지고 있습니다.

이미 비즈니스 로직이 모두 분리되어있는 경우 사과해야 겠지만 실제 비즈니스 로직을 확인해야하는 외에 ASP.Net 런타임 외부의 서버 컨트롤을 테스트해야하는 다른 이유는 생각할 수 없습니다. 이 인 경우 리팩토링하는 것이 좋습니다. 유지 보수의 어려움을 깨닫기 전에 결국 Leaky Abstractions을 통해 해결할 것입니다.