2010-08-13 3 views
5

MVC 3 미리보기 1을 사용하여 새로운 면도기 뷰 엔진을 시험해보고 NUnit/Moq를 사용하여 간단한 단위 테스트를 작성하고 싶습니다. Razor의 실제 판매 기능 중 하나인데도 실제로이 작업이 아직 수행되지 않은 사례는 없습니다.면도기 기반 뷰에 대한 단위 테스트를 작성하기위한 포인터가 필요합니다.

컨트롤러가있는 경우 DBConext 개체 (EF4 CTP 코드)가 먼저 사용되며 컨트롤러에서 호출 된 모델에 제공된 항목 목록에 따라 드롭 다운 목록이 렌더링됩니다 요소에 항목이 채워져 있는지 테스트 할 수 있기를 바랍니다. 여기

public class WeatherReportController : Controller, IWeatherReportController 
{ 
    private IWeatherDb _weatherDb; 

    public WeatherReportController() 
    { 
     this._weatherDb = new WeatherDb(); 
    } 

    public ActionResult Index() 
    { 
     WeatherReportIndexModel model = new WeatherReportIndexModel 
     { 
      Report = new WeatherReport { 
       Username = this.HttpContext.User.Identity.Name, 
       WeatherType = new WeatherType() 
      }, 
      WeatherTypeList = _weatherDb.GetAllWeatherTypes() 
     }; 
     return View(model); 
    } 

} 

내 모델의 :

public class WeatherReportIndexModel 
{ 
    private IList<WeatherType> _weatherTypeList = new List<WeatherType>(); 
    public IList<WeatherType> WeatherTypeList { 
     get 
     { 
      return _weatherTypeList; 
     } 
     set 
     { 
      _weatherTypeList = value; 
     } 
    } 

    [DisplayName("Type of Weather")] 
    public IList<SelectListItem> WeatherTypeSelectItemList 
    { 
     get 
     { 
      int id = this.Report.WeatherType == null ? 0 : this.Report.WeatherType.WeatherTypeId; 
      List<SelectListItem> selectListItems = this.WeatherTypeList.Select(weatherType => new SelectListItem 
                        { 
                         Value = weatherType.WeatherTypeId.ToString(), 
                         Text = weatherType.Name, 
                         Selected = weatherType.WeatherTypeId == id 
                        }).ToList(); 
      selectListItems.Insert(0, new SelectListItem { Selected = (this.Report.WeatherType == null), Text = "Select Type of Weather", Value = "0" }); 
      return selectListItems; 
     } 
    } 

    public WeatherReport Report { get; set; } 
} 

그리고 여기 내보기입니다 :

다음과
@inherits System.Web.Mvc.WebViewPage<Web.UI.Models.WeatherReportIndexModel> 

@{ 
    View.Title = "Index"; 
    LayoutPage = "~/Views/Shared/_Layout.cshtml"; 
} 

<h2>Index</h2> 


@using (Html.BeginForm()) { 
    <div> 
     <fieldset> 
      <legend>New Weather Report</legend> 
      <div class="editor-label"> 
       @Html.LabelFor(m => m.Report.WeatherType.WeatherTypeId) 
       @Html.DropDownListFor(m => m.Report.WeatherType.WeatherTypeId, Model.WeatherTypeSelectItemList) 
    <input type="submit" value="Log On" /> 
      </div> 
    </fieldset> 
</div> 
} 

내가 지금까지 가지고있는 테스트 코드가 될 때 : 여기

내 컨트롤러의

[TestFixture] 
public class WeatherReportViewTests 
{ 
    [Test] 
    public void Can_render_weather_report_index_view_correctly() 
    { 

     var mockControllerContext = new Mock<ControllerContext>(); 
     var mockSession = new Mock<HttpSessionStateBase>(); 

     mockControllerContext.Setup(p => p.HttpContext.Request.HttpMethod).Returns("POST"); 
     mockControllerContext.Setup(p => p.HttpContext.Request.UserHostAddress).Returns("1.1.1.1"); 
     mockControllerContext.Setup(p => p.HttpContext.Session).Returns(mockSession.Object); 
     mockControllerContext.Setup(p => p.HttpContext.Request.LogonUserIdentity).Returns(WindowsIdentity.GetCurrent()); 

     var routeData = new RouteData(); 
     routeData.Values.Add("controller", "WeatherReport"); 
     routeData.Values.Add("action", "Index"); 

     var viewEngine = new CshtmlViewEngine(); 
     var view = viewEngine.FindView(mockControllerContext.Object, "Index", "_Layout", false); 
     var viewReponse = view.ToString(); 

     Assert.That(viewReponse, Contains.Substring("Sunny Intervals")); 
    } 
} 

테스트를 실행할 때 NullReferenceException이 발생합니다.

모든 아이디어/포인터 등을 환영합니다. 나는 미래에 내 의견에 TDD를 할 수 있도록이 일을하고 싶습니다.

미리 감사드립니다.

+0

죄송합니다. 내 테스트 코드를 업데이트 했는데도 여전히 내 머리를 긁적입니다. ( – dextermixwith

+0

아직 행운이 있습니까? 이 기능을 공유 할 수있는 방법을 찾았습니다 ... thx –

답변

2

나는 CshtmlViewEngine 클래스를 피하고 Razor 엔진을 직접 실행하는 것이 좋습니다. RAZOR 뷰를 ASPX 외부에서 컴파일하는 것에 대한 블로그 포스트를 작성했습니다 : http://vibrantcode.com/blog/2010/7/22/using-the-razor-parser-outside-of-aspnet.html

MVC3의 미리보기 1에서는 Razor 엔진이 System.Web.Mvc에 포함되어 공개 (IIRC)되어 있으므로 찾을 수 있어야합니다. 해당 게시물/샘플 System.Web.Mvc.dll에서 참조되는 모든 클래스.

일단 페이지를 컴파일하고 생성 된 클래스를로드하고 조롱 한 컨텍스트 개체를 전달한 다음 Execute()를 호출하면됩니다. 페이지에 대한 CodeDOM 트리가 있으므로 (Razor 엔진을 사용할 때) 기본 클래스를 조정하여 System.Web.Mvc.WebViewPage 대신 테스트 페이지 기본 클래스에서 상속되므로 대체 컨텍스트 객체 등을 교환하십시오.

+4

감사합니다. 나는 믿을 수있게 이끌어 준 것처럼 어디에서나 똑바로 들린다. (나는 그것을 시도해 보겠다.) Soudns는 인내심을 가지고 면도기의 새로운 방출을 기다릴 필요가 있을지도 모른다. – dextermixwith

+0

나는 그것이 아주 간단하지 않다는 것에 동의한다. 그러나 Razor는 사람들이 ASP를로드하지 않고도 Razor보기 페이지를 실제로 실행할 수있는 테스트 장치를 작성할 수있는 능력을 획기적으로 향상시킵니다.닷넷 (HTTP 컨텍스트와 다른 ASP.Net과 같은 프레임 워크 요소를 조롱해야하지만보기가 닿아 야합니다.) –

+0

면도날에 면도날에 메모리에 코드를 컴파일 할 필요는 없지만 그 코드는 작동합니다. – mfloryan

0

면도기 테스트에 대해 썼습니다. 그것은 추악하고 모든 종류의 불쾌한 일이지만 작동하고 모든 프로젝트에서 내 모든 견해를 테스트하기 위해 그것을 적용 할 수있었습니다.

http://httputility.com/articles/unit-testing-razor-views.html

오래 살았 프로젝트를 위해 내가 MVC 팀에 의해 테스트 하네스를 기다리고 제안했지만.

관련 문제