有没有办法(单元)测试我自己的HtmlHelpers?如果我想要自定义控件(由HtmlHelper呈现)并且我知道该控件的需求,我怎么能先编写测试 - 然后编写代码?有没有特定的(好的)方法呢?
这值得吗?
主要问题是你必须模拟HtmlHelper,因为你可能正在使用帮助器的方法来获取路由或值或返回另一个扩展方法的结果.HtmlHelper类具有相当多的属性,其中一些非常复杂,如ViewContext或当前的Controller.
Ben Hart的这篇文章解释了如何使用Moq创建这样的模拟.可以很容易地翻译成另一个模拟框架.
这是我的Rhino Mocks版本,适应MVC框架的变化.它没有经过全面测试,但它对我有用,但不要指望完美的结果:
public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData) { var mocks = new MockRepository(); var cc = mocks.DynamicMock( mocks.DynamicMock (), new RouteData(), mocks.DynamicMock ()); var mockViewContext = mocks.DynamicMock ( cc, mocks.DynamicMock (), viewData, new TempDataDictionary()); var mockViewDataContainer = mocks.DynamicMock (); mockViewDataContainer.Expect(v => v.ViewData).Return(viewData); return new HtmlHelper(mockViewContext, mockViewDataContainer); }
如果有人正在寻找如何创建HtmlHelper
(这就是我所追求的),这里有一个可能有用的实现 - 我的类型是一个名为Model的类:
public static HtmlHelperCreateHtmlHelper() { ViewDataDictionary vd = new ViewDataDictionary(new Model()); var controllerContext = new ControllerContext(new Mock ().Object, new RouteData(), new Mock ().Object); var viewContext = new ViewContext(controllerContext, new Mock ().Object, vd, new TempDataDictionary(), new Mock ().Object); var mockViewDataContainer = new Mock (); mockViewDataContainer.Setup(v => v.ViewData).Returns(vd); return new HtmlHelper (viewContext, mockViewDataContainer.Object); }
或者更通用的实现:
public HtmlHelperCreateHtmlHelper () where T : new() { var vd = new ViewDataDictionary(new T()); var controllerContext = new ControllerContext(new Mock ().Object, new RouteData(), new Mock ().Object); var viewContext = new ViewContext(controllerContext, new Mock ().Object, vd, new TempDataDictionary(), new Mock ().Object); var mockViewDataContainer = new Mock (); mockViewDataContainer.Setup(v => v.ViewData).Returns(vd); return new HtmlHelper (viewContext, mockViewDataContainer.Object); }