I’ve been trying for a while now to write a unit test for a UserViewControl in ASP.NET MVC. I’d like to get to code that looks something like this:
[TestMethod] public void HaveControlToDisplayThings() { var listControl = new ControlUnderTest(); var viewData = new ViewDataDictionary<IList<string>>(this.repo.GetMeSomeData()); // Set up a ViewContext using Moq. listControl.SetFakeViewContext(viewData); listControl.ViewData = viewData; listControl.RenderView(listControl.ViewContext); // Never got this far, no idea if this will work :) string s = listControl.ViewContext.HttpContext.Response.Output.ToString(); Assert.AreNotEqual(0, s.Length); foreach (var item in this.repo.GetMeSomeData()) { Assert.IsTrue(s.IndexOf(item) != -1); } }
Unfortunately, no matter what I try I get errors from deep inside RenderView. This is caused (as far as I can tell) by the static HttpContext.Current object being useless – I get NullReferenceExceptions from System.Web.UI.Page.SetIntrinsics.
I tried using Phil Haack’s HttpSimulator which gave me a HttpContext object but I found I also needed to specify a fake HttpBrowserCapabilities object to get slightly further:
Subtext.TestLibrary.HttpSimulator simulator = new HttpSimulator(); simulator.SimulateRequest(); var browserMock = new Mock<HttpBrowserCapabilities>(); browserMock.Expect(b => b.PreferredRenderingMime).Returns('text/html'); browserMock.Expect(b => b.PreferredResponseEncoding).Returns('UTF-8'); browserMock.Expect(b => b.PreferredRequestEncoding).Returns('UTF-8'); HttpContext.Current.Request.Browser = browserMock.Object;
Now I get exceptions on property accesses on that object. I mocked as many as I could, but seemed to be getting nowhere fast.
Has anyone managed to make this work?
Unfortunately, the ASP.NET viewengine uses the VirtualPathProvider in the ASP.NET hosting environment. To make matters worse, I traced some of the other code using Reflector and found that there is other dependencies to some hardcode references to VirtualPath utilities. I hope they fix this in the release so we can truly test our Views and how they are rendered.