【问题标题】:MissingMethodException thrown when trying to mock HtmlHelper with Moq尝试使用 Moq 模拟 HtmlHelper 时抛出 MissingMethodException
【发布时间】:2010-08-10 03:11:02
【问题描述】:

在尝试关注article on mocking the htmlhelper with Moq 时,我遇到了以下问题。创建 htmlhelper 时会引发异常。我只是猜测城堡温莎正在被使用(通过查看错误消息)。

例外:

发生MissingMethodException

找不到类型“Castle.Proxies.ViewContextProxy”的构造函数。

堆栈跟踪:

在 System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfoculture, 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 实例?

【问题讨论】:

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


    【解决方案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

    【讨论】:

    • 此答案与 Igor Zevaka 提供的答案之间的主要区别在于 Mock 是使用 Mock().Object 创建的。
    • 我刚刚在 MVC 4 上尝试过这个,我在 Html.ViewContext.ViewData 上得到了空引用异常,看起来很多 MVC 内部代码都在使用它。你有机会更新上面的代码吗?编辑:我想我想通了,我将编辑上面的代码。
    • 代码已由@anon 更新并针对 MVC 4 进行了验证。
    【解决方案2】:

    当 MOQ 无法将 Mock&lt;&gt;() 的参数与模拟类的构造函数上的参数匹配时,您会得到 MissingMethodException

    查看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 使用 Dynamic Proxy 项目,但它们是截然不同的项目。

    【讨论】:

    • 我们肯定走在正确的轨道上——现在的错误是:发生 MissingMethodException:找不到成员。 StackTrace:在 System.DefaultBinder.BindToMethod(BindingFlags bindingAttr, MethodBase[] match, Object[]& args, ParameterModifier[] 修饰符, CultureInfocultureInfo, String[] names, Object& state) 有什么想法吗?
    • Havard S,这篇文章的原作者很乐意回答我的问题,将更新发布到他的博客,并将解决方案也发布到 SO。你非常非常非常接近,我希望我也能奖励你“答案”。
    • 哦,当然,我忘了做.Object。不用担心,我会更新答案,以便对其他人正确。
    猜你喜欢
    • 2011-06-27
    • 2019-07-07
    • 2017-07-11
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    相关资源
    最近更新 更多