gpt4 book ai didi

asp.net-mvc - 需要为基于 Razor 的 View 编写单元测试的指针

转载 作者:行者123 更新时间:2023-12-04 21:25:44 24 4
gpt4 key购买 nike

我正在使用 MVC 3 Preview 1 试用新的 Razor View 引擎,并且真的很想使用 NUnit/Moq 编写一个简单的单元测试。我还没有看到任何实际完成的例子——尽管它是 Razor 的真正销售功能之一。

因此,如果我有一个 Controller ,它使用 DBConext 对象(EF4 CTP 代码优先),并且 View 会根据在 Controller 上调用的操作中加载的模型中提供的项目列表呈现下拉列表,我会喜欢能够测试元素是否填充了项目。

这是我的 Controller :

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。

提前致谢!

最佳答案

我建议完全避免使用 CshtmlViewEngine 类并自己启动 Razor 引擎。我在这里写了一篇关于在 ASPX 之外编译 Razor View 的博客文章:http://vibrantcode.com/blog/2010/7/22/using-the-razor-parser-outside-of-aspnet.html

在 MVC3 的 Preview 1 中,Razor 引擎嵌入在 System.Web.Mvc 中并且是公共(public)的 (IIRC),因此您应该能够在 System.Web.Mvc.dll 中找到该帖子/示例中引用的所有类。

编译页面后,只需加载生成的类,传入模拟出来的上下文对象,然后调用 Execute()。因为你有一个页面的 CodeDOM 树(当你使用 Razor 引擎时),你甚至可以调整基类,以便它继承自一个测试页面基类,而不是 System.Web.Mvc.WebViewPage,让你交换替换上下文对象等。

关于asp.net-mvc - 需要为基于 Razor 的 View 编写单元测试的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3476609/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com