我有一个问题,试图创建一个单元测试来测试自定义剃刀助手(使用kendo网格剃刀助手)。
问题来自kendo网格助手,它试图访问以下属性:HtmlHelper.ViewContext.Controller.ValueProvider
(并抛出NullReferenceException
。此异常来自对控制器上下文的ValueProvider
属性的访问)。
我总结说我的"模拟" http /控制器上下文未正确初始化。我尝试在互联网上找到的几种解决方案来模拟上下文,但我仍然有问题)。
这是我目前的单元测试代码:
ModelMock model = ...
ViewDataDictionary vd = new ViewDataDictionary(model);
var htmlHelper = CreateHtmlHelper<ModelMock>(vd);
string htmlResult = htmlHelper.PopinGrid(m => m.JsonList).ToHtmlString(); // This is the call of my helper.
... (asserts)
我帮助你进行上下文模拟(他们使用其他简单的剃刀助手单元测试):
public static HtmlHelper<T> CreateHtmlHelper<T>(ViewDataDictionary viewDataDictionary)
where T : new()
{
Mock<ControllerBase> controller = new Mock<ControllerBase>();
Mock<ControllerContext> controllerContext = new Mock<ControllerContext>(
new Mock<HttpContextBase>().Object,
new RouteData(),
controller.Object);
Mock<ViewContext> viewContext = new Mock<ViewContext>(
controllerContext.Object,
new Mock<IView>().Object,
viewDataDictionary,
new TempDataDictionary(),
new StringWriter(CultureInfo.InvariantCulture));
Mock<IViewDataContainer> mockViewDataContainer = new Mock<IViewDataContainer>();
bool unobtrusiveJavascriptEnabled = false;
bool clientValidationEnabled = true;
viewContext.SetupGet(c => c.UnobtrusiveJavaScriptEnabled).Returns(unobtrusiveJavascriptEnabled);
viewContext.SetupGet(c => c.FormContext).Returns(new FormContext { FormId = "myForm" });
viewContext.SetupGet(c => c.ClientValidationEnabled).Returns(clientValidationEnabled);
viewContext.SetupGet(c => c.ViewData).Returns(viewDataDictionary);
// I add the following line because the "Controller" property of the viewContext was null (strange, given that I initialize the view context with the controller context).
viewContext.SetupGet(c => c.Controller).Returns(controller.Object);
mockViewDataContainer.Setup(v => v.ViewData).Returns(viewDataDictionary);
HttpContext.Current = FakeHttpContext();
return new HtmlHelper<T>(viewContext.Object, mockViewDataContainer.Object);
}
public static HttpContext FakeHttpContext()
{
HttpRequest httpRequest = new HttpRequest(string.Empty, "http://mockurl/", string.Empty);
StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
HttpResponse httpResponse = new HttpResponse(stringWriter);
HttpContext httpContext = new HttpContext(httpRequest, httpResponse);
HttpSessionStateContainer sessionContainer = new HttpSessionStateContainer(
"id",
new SessionStateItemCollection(),
new HttpStaticObjectsCollection(),
10,
true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc,
false);
httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
CallingConventions.Standard,
new[] { typeof(HttpSessionStateContainer) },
null)
.Invoke(new object[] { sessionContainer });
return httpContext;
}
有人知道模拟完整的http /控制器上下文的好方法吗?
谢谢!