尝试使用Moq模拟HtmlHelper时抛出MissingMethodException

时间:2010-08-10 03:11:03

标签: asp.net-mvc unit-testing mocking moq

尝试关注article on mocking the htmlhelper with Moq时,我遇到了以下问题。创建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);
    }

我正在使用ASP MVC 2,Moq 4.0 beta 3,VS2010,使用IDE的测试框架。

如何解决问题并返回HtmlHelper的实例?

2 个答案:

答案 0 :(得分:6)

当MOQ无法将参数MissingMethodException与模拟类的构造函数上的参数匹配时,会得到Mock<>()

ViewContext解释原因。只有一个构造函数重载,它是这样的:

 public ViewContext(ControllerContext controllerContext, IView view, ViewDataDictionary viewData, TempDataDictionary tempData, TextWriter writer);

此设置(包括缺少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);

PS MOQ使用Castle Dynamic Proxy在运行时创建模拟类,因此在您看到的异常中名称为Castle。 Castle Windsor使用动态代理项目,但它们是完全不同的项目。

答案 1 :(得分:1)

我已经使用我博客文章中的代码重现了您的问题。以下更新的方法适用于我:

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);
}

我也发布了update on my blog