Med*_*Man 4 asp.net-mvc unit-testing moq mocking
当试图跟随关于使用Moq模拟htmlhelper的文章时,我遇到了以下问题.创建htmlhelper时会抛出异常.我只是猜测正在使用城堡windsor(通过查看错误消息).
例外:
发生了MissingMethodException
找不到类型为"Castle.Proxies.ViewContextProxy"的构造函数.
堆栈跟踪:
在System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr,Binder binder,Object [] args,CultureInfo culture,Object [] activationAttributes)
代码:
public static HtmlHelper CreateHtmlHelper(ViewDataDictionary vd)
{
Mock<ViewContext> mockViewContext = new Mock<ViewContext>(
new ControllerContext(
new Mock<HttpContextBase>().Object,
new RouteData(),
new Mock<ControllerBase>().Object),
new Mock<IView>().Object,
vd,
new TempDataDictionary());
Mock<IViewDataContainer> mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.Setup(v => v.ViewData).Returns(vd);
return new HtmlHelper(mockViewContext.Object, mockViewDataContainer.Object);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用ASP MVC 2,Moq 4.0 beta 3,VS2010,使用IDE的测试框架.
如何解决问题并返回HtmlHelper的实例?
MissingMethodException当MOQ无法Mock<>()将参数与mocked类的构造函数上的参数匹配时,就会得到.
看着ViewContext解释原因.只有一个构造函数重载,它是这样的:
public ViewContext(ControllerContext controllerContext, IView view, ViewDataDictionary viewData, TempDataDictionary tempData, TextWriter writer);
Run Code Online (Sandbox Code Playgroud)
此设置(包括缺少TextWriter模拟)应该工作:
Mock<ViewContext> mockViewContext = new Mock<ViewContext>(
new ControllerContext(
new Mock<HttpContextBase>().Object,
new RouteData(),
new Mock<ControllerBase>().Object),
new Mock<IView>().Object,
vd,
new TempDataDictionary()
new Mock<TextWriter>().Object);
Run Code Online (Sandbox Code Playgroud)
PS MOQ使用Castle Dynamic Proxy在运行时创建模拟类,因此在您看到的异常中名称为Castle.Castle Windsor使用动态代理项目,但它们是完全不同的项目.
我已使用我的博客文章中的代码重现了您的问题。以下更新的方法对我有用:
public static HtmlHelper CreateHtmlHelper(ViewDataDictionary vd)
{
Mock<ViewContext> mockViewContext = new Mock<ViewContext>(
new ControllerContext(
new Mock<HttpContextBase>().Object,
new RouteData(),
new Mock<ControllerBase>().Object),
new Mock<IView>().Object,
vd,
new TempDataDictionary(),
new Mock<TextWriter>().Object);
mockViewContext.Setup(vc => vc.ViewData).Returns(vd);
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.Setup(v => v.ViewData)
.Returns(vd);
return new HtmlHelper(mockViewContext.Object,
mockViewDataContainer.Object);
}
Run Code Online (Sandbox Code Playgroud)
我也在我的博客上发布了更新。