2010-08-13 14 views
5

Estoy probando el nuevo motor Razor view con MVC 3 Preview 1 y realmente me gustaría escribir una prueba simple de unidad usando NUnit/Moq. No he visto ningún ejemplo de esto realmente hecho, a pesar de ser una de las características de venta reales en Razor.Punteros para escribir una prueba unitaria para una vista basada en Navaja necesaria

Entonces, si tengo un controlador, utiliza un objeto DBConext (código EF4 CTP primero) y la vista representa una lista desplegable basada en una lista de elementos proporcionados en un modelo cargado en una acción llamada al controlador , Me gustaría poder probar que el elemento tiene elementos llenos en él.

Aquí está mi controlador:

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

} 

Aquí es mi modelo:

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

Y aquí es mi opinión:

@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> 
} 

El código de prueba que tengo hasta ahora es la siguiente:

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

Al ejecutar la prueba, solo obtengo una NullReferenceException.

Cualquier idea/punteros, etc. sería bienvenida. Realmente me gustaría hacer que esto funcione, así que puedo hacer TDD sobre mis puntos de vista en el futuro.

¡Gracias de antemano!

+0

Lo sentimos - sólo realiza una actualización de mi código de prueba - todavía rascándome la cabeza, aunque :( – dextermixwith

+0

habido suerte todavía te he encontrado una manera de hacer esta funcionales por favor, compartir ... THX –

Respuesta

2

Sugeriría evitar por completo la clase CshtmlViewEngine y activar el motor Razor usted mismo. Escribí una publicación en un blog sobre cómo compilar vistas Razor fuera de ASPX aquí: http://vibrantcode.com/blog/2010/7/22/using-the-razor-parser-outside-of-aspnet.html

En la Vista previa 1 de MVC3, el motor Razor está incrustado en System.Web.Mvc y es público (IIRC), por lo que debería poder encontrar todas las clases a las que se hace referencia en esa publicación/muestra en System.Web.Mvc.dll.

Una vez que haya compilado la página, solo cargue la clase generada, pase los objetos de contexto burlados y llame a Execute(). Como tiene un árbol CodeDOM para la página (cuando usa el motor Razor), incluso puede modificar la clase base para que, en lugar de System.Web.Mvc.WebViewPage, herede de una clase base de la página de prueba que le permite intercambiar en objetos de contexto de reemplazo, etc.

+4

Gracias por eso? - doesn No suena ni de lejos tan simple como me llevaron a creer :(Voy a intentarlo Soudns como que necesito ser paciente y esperar un nuevo lanzamiento de Razor. – dextermixwith

+0

Estoy de acuerdo en que no es muy sencillo aún así, pero creo que Razor mejora dramáticamente la capacidad de las personas para escribir arneses de prueba que realmente pueden ejecutar una página de vista Razor completa sin tener que cargar ASP.Net (aunque tiene que burlarse de elementos del framework, como HTTP Context y otras cosas de ASP.Net que toca su vista). –

+0

No esperaba tener que compilar código en la memoria sobre la marcha para encender Razor, pero diablos funciona. – mfloryan

0

He escrito sobre pruebas de unidad Vistas de maquinilla de afeitar. Es feo y todo desagradable, pero funciona y pude adaptarlo para probar todos mis puntos de vista en todos los proyectos.

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

Aunque para proyectos de larga vida que sugeriría la espera de un instrumento de prueba realizado por el equipo de MVC.

Cuestiones relacionadas